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.

1762 lines
48 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. fhclicfg.cpp
  5. Abstract:
  6. Client configuration class
  7. Revision History:
  8. created derekm 03/31/00
  9. ******************************************************************************/
  10. #include "stdafx.h"
  11. #include "pfrcfg.h"
  12. // allow the configuration to be settable
  13. #define ENABLE_SRV_CONFIG_SETTING 1
  14. /////////////////////////////////////////////////////////////////////////////
  15. // defaults
  16. const EEnDis c_eedDefShowUI = eedEnabled;
  17. const EEnDis c_eedDefReport = eedEnabled;
  18. const EIncEx c_eieDefShutdown = eieExclude;
  19. const EEnDis c_eedDefShowUISrv = eedDisabled;
  20. const EEnDis c_eedDefReportSrv = eedDisabled;
  21. const EIncEx c_eieDefShutdownSrv = eieInclude;
  22. const EEnDis c_eedDefTextLog = eedDisabled;
  23. const EIncEx c_eieDefApps = eieInclude;
  24. const EIncEx c_eieDefKernel = eieInclude;
  25. const EIncEx c_eieDefMSApps = eieInclude;
  26. const EIncEx c_eieDefWinComp = eieInclude;
  27. const BOOL c_fForceQueue = FALSE;
  28. const BOOL c_fForceQueueSrv = TRUE;
  29. const DWORD c_cDefHangPipes = c_cMinPipes;
  30. const DWORD c_cDefFaultPipes = c_cMinPipes;
  31. const DWORD c_cDefMaxUserQueue = 10;
  32. #if defined(DEBUG) || defined(_DEBUG)
  33. const DWORD c_dwDefInternal = 1;
  34. #else
  35. const DWORD c_dwDefInternal = 0;
  36. #endif
  37. const WCHAR c_wszDefSrvI[] = L"officewatson";
  38. const WCHAR c_wszDefSrvE[] = L"watson.microsoft.com";
  39. /////////////////////////////////////////////////////////////////////////////
  40. // utility
  41. // **************************************************************************
  42. HRESULT AddToArray(SAppList &sal, SAppItem *psai)
  43. {
  44. USE_TRACING("AddToArray");
  45. HRESULT hr = NOERROR;
  46. DWORD i = sal.cSlotsUsed;
  47. BOOL fUseFreedSlot = FALSE;
  48. // first, skim thru the array & see if there are any empty slots
  49. if (sal.cSlotsEmpty > 0 && sal.rgsai != NULL)
  50. {
  51. for (i = 0; i < sal.cSlotsUsed; i++)
  52. {
  53. if (sal.rgsai[i].wszApp == NULL)
  54. {
  55. sal.cSlotsEmpty--;
  56. fUseFreedSlot = TRUE;
  57. break;
  58. }
  59. }
  60. }
  61. // nope, see if we need to grow the array
  62. if (sal.cSlotsUsed >= sal.cSlots && fUseFreedSlot == FALSE)
  63. {
  64. SAppItem *rgsai = NULL;
  65. DWORD cSlots;
  66. if (sal.cSlots == 0)
  67. cSlots = 16;
  68. else
  69. cSlots = 2 * sal.cSlots;
  70. rgsai = (SAppItem *)MyAlloc(cSlots * sizeof(SAppItem));
  71. VALIDATEEXPR(hr, (rgsai == NULL), E_OUTOFMEMORY);
  72. if (FAILED(hr))
  73. goto done;
  74. if (sal.rgsai != NULL)
  75. {
  76. CopyMemory(rgsai, sal.rgsai, sal.cSlots * sizeof(SAppItem));
  77. MyFree(sal.rgsai);
  78. }
  79. sal.rgsai = rgsai;
  80. sal.cSlots = cSlots;
  81. }
  82. // if we are appending, then gotta increase cSlotsUsed
  83. if (sal.cSlotsUsed == i)
  84. sal.cSlotsUsed++;
  85. sal.rgsai[i].dwState = psai->dwState;
  86. sal.rgsai[i].wszApp = psai->wszApp;
  87. done:
  88. return hr;
  89. }
  90. // **************************************************************************
  91. BOOL ClearCPLDW(HKEY hkeyCPL)
  92. {
  93. DWORD dw;
  94. WCHAR wch = L'\0';
  95. BOOL fCleared = FALSE;
  96. HKEY hkeyDW = NULL;
  97. if (hkeyCPL == NULL)
  98. return TRUE;
  99. // first, try deleting the key. If that succeeded or it doesn't exist,
  100. // then we're done.
  101. dw = RegDeleteKeyW(hkeyCPL, c_wszRKDW);
  102. if (dw == ERROR_SUCCESS || dw == ERROR_PATH_NOT_FOUND ||
  103. dw == ERROR_FILE_NOT_FOUND)
  104. {
  105. fCleared = TRUE;
  106. goto done;
  107. }
  108. // Otherwise, need to open the key
  109. dw = RegOpenKeyExW(hkeyCPL, c_wszRKDW, 0, KEY_READ | KEY_WRITE, &hkeyDW);
  110. if (dw != ERROR_SUCCESS)
  111. goto done;
  112. // try to delete the file path value from it.
  113. dw = RegDeleteValueW(hkeyDW, c_wszRVDumpPath);
  114. if (dw == ERROR_SUCCESS || dw == ERROR_PATH_NOT_FOUND ||
  115. dw == ERROR_FILE_NOT_FOUND)
  116. {
  117. fCleared = TRUE;
  118. goto done;
  119. }
  120. // ok, last try. Try to write an empty string to the value
  121. dw = RegSetValueExW(hkeyDW, c_wszRVDumpPath, 0, REG_SZ, (LPBYTE)wch,
  122. sizeof(wch));
  123. if (dw == ERROR_SUCCESS)
  124. {
  125. fCleared = TRUE;
  126. goto done;
  127. }
  128. done:
  129. if (hkeyDW != NULL)
  130. RegCloseKey(hkeyDW);
  131. return fCleared;
  132. }
  133. /////////////////////////////////////////////////////////////////////////////
  134. // CPFFaultClientCfg- init & term
  135. // **************************************************************************
  136. CPFFaultClientCfg::CPFFaultClientCfg()
  137. {
  138. OSVERSIONINFOEXW osvi;
  139. INIT_TRACING
  140. USE_TRACING("CPFFaultClientCfg::CPFFaultClientCfg");
  141. InitializeCriticalSection(&m_cs);
  142. ZeroMemory(m_wszDump, sizeof(m_wszDump));
  143. ZeroMemory(m_wszSrv, sizeof(m_wszSrv));
  144. ZeroMemory(m_rgLists, sizeof(m_rgLists));
  145. ZeroMemory(&osvi, sizeof(osvi));
  146. osvi.dwOSVersionInfoSize = sizeof(osvi);
  147. GetVersionExW((OSVERSIONINFOW *)&osvi);
  148. if (osvi.wProductType == VER_NT_SERVER)
  149. {
  150. m_eieShutdown = c_eieDefShutdownSrv;
  151. m_fForceQueue = c_fForceQueueSrv;
  152. m_fSrv = TRUE;
  153. }
  154. else
  155. {
  156. m_eieShutdown = c_eieDefShutdown;
  157. m_fForceQueue = c_fForceQueue;
  158. m_fSrv = FALSE;
  159. }
  160. m_eedUI = c_eedDefShowUI;
  161. m_eedReport = c_eedDefReport;
  162. m_eieApps = c_eieDefApps;
  163. m_eedTextLog = c_eedDefTextLog;
  164. m_eieMS = c_eieDefMSApps;
  165. m_eieWin = c_eieDefWinComp;
  166. m_eieKernel = c_eieDefKernel;
  167. m_cFaultPipes = c_cDefFaultPipes;
  168. m_cHangPipes = c_cDefHangPipes;
  169. m_cMaxQueueItems = c_cDefMaxUserQueue;
  170. m_dwStatus = 0;
  171. m_dwDirty = 0;
  172. m_pbWinApps = NULL;
  173. m_fRead = FALSE;
  174. m_fRO = FALSE;
  175. }
  176. // **************************************************************************
  177. CPFFaultClientCfg::~CPFFaultClientCfg(void)
  178. {
  179. this->Clear();
  180. DeleteCriticalSection(&m_cs);
  181. }
  182. // **************************************************************************
  183. void CPFFaultClientCfg::Clear(void)
  184. {
  185. USE_TRACING("CPFFaultClientCfg::Clear");
  186. DWORD i;
  187. for(i = 0; i < epfltListCount; i++)
  188. {
  189. if (m_rgLists[i].hkey != NULL)
  190. RegCloseKey(m_rgLists[i].hkey);
  191. if (m_rgLists[i].rgsai != NULL)
  192. {
  193. DWORD iSlot;
  194. for (iSlot = 0; iSlot < m_rgLists[i].cSlotsUsed; iSlot++)
  195. {
  196. if (m_rgLists[i].rgsai[iSlot].wszApp != NULL)
  197. MyFree(m_rgLists[i].rgsai[iSlot].wszApp);
  198. }
  199. MyFree(m_rgLists[i].rgsai);
  200. }
  201. }
  202. ZeroMemory(m_wszDump, sizeof(m_wszDump));
  203. ZeroMemory(m_wszSrv, sizeof(m_wszSrv));
  204. ZeroMemory(m_rgLists, sizeof(m_rgLists));
  205. if (m_fSrv)
  206. {
  207. m_eieShutdown = c_eieDefShutdownSrv;
  208. m_fForceQueue = c_fForceQueueSrv;
  209. }
  210. else
  211. {
  212. m_eieShutdown = c_eieDefShutdown;
  213. m_fForceQueue = c_fForceQueue;
  214. }
  215. m_eedUI = c_eedDefShowUI;
  216. m_eedReport = c_eedDefReport;
  217. m_eieApps = c_eieDefApps;
  218. m_eedTextLog = c_eedDefTextLog;
  219. m_eieMS = c_eieDefMSApps;
  220. m_eieWin = c_eieDefWinComp;
  221. m_eieKernel = c_eieDefKernel;
  222. m_cFaultPipes = c_cDefFaultPipes;
  223. m_cHangPipes = c_cDefHangPipes;
  224. m_cMaxQueueItems = c_cDefMaxUserQueue;
  225. m_dwStatus = 0;
  226. m_dwDirty = 0;
  227. m_pbWinApps = NULL;
  228. m_fRead = FALSE;
  229. m_fRO = FALSE;
  230. }
  231. /////////////////////////////////////////////////////////////////////////////
  232. // CPFFaultClientCfg- exposed
  233. // **************************************************************************
  234. HRESULT CPFFaultClientCfg::Read(EReadOptions ero)
  235. {
  236. USE_TRACING("CPFFaultClientCfg::Read");
  237. CAutoUnlockCS aucs(&m_cs);
  238. HRESULT hr = NOERROR;
  239. WCHAR wch = L'\0', *wszDefSrv;
  240. DWORD cb, dw, i, cKeys = 0, iReport = 0, iShowUI = 0;
  241. DWORD dwOpt;
  242. HKEY rghkeyCfg[2], hkeyCfgDW = NULL, hkeyCPL = NULL;
  243. BOOL fHavePolicy = FALSE;
  244. // this will automatically unlock when the fn exits
  245. aucs.Lock();
  246. dwOpt = (ero == eroCPRW) ? orkWantWrite : 0;
  247. this->Clear();
  248. rghkeyCfg[0] = NULL;
  249. rghkeyCfg[1] = NULL;
  250. // if we open read-only, then we will also try to read from the policy
  251. // settings cuz they override the control panel settings. If the user
  252. // wants write access, then we don't bother cuz we don't support writing
  253. // to the policy keys via this object.
  254. // We use the RegOpenKeyEx function directly here cuz I don't want to
  255. // create the key if it doesn't exist (and that's what OpenRegKey will do)
  256. if (ero == eroPolicyRO)
  257. {
  258. TESTERR(hr, RegOpenKeyExW(HKEY_LOCAL_MACHINE, c_wszRPCfgPolicy, 0,
  259. KEY_READ | KEY_WOW64_64KEY, &rghkeyCfg[0]));
  260. if (SUCCEEDED(hr))
  261. {
  262. cKeys = 1;
  263. fHavePolicy = TRUE;
  264. DBG_MSG("policy found");
  265. }
  266. }
  267. // open the control panel reg key
  268. TESTHR(hr, OpenRegKey(HKEY_LOCAL_MACHINE, c_wszRPCfg, 0,
  269. &rghkeyCfg[cKeys]));
  270. if (SUCCEEDED(hr))
  271. {
  272. // need to check if a filepath exists in the DW control panel key. If
  273. // so, disable reporting & enable the UI (if reporting was enabled)
  274. if (ClearCPLDW(rghkeyCfg[cKeys]) == FALSE)
  275. m_dwStatus |= CPL_CORPPATH_SET;
  276. hkeyCPL = rghkeyCfg[cKeys];
  277. cKeys++;
  278. }
  279. // if we couldn't open either key successfully, then we don't need to do
  280. // anything else. The call to 'this->Clear()' above has already set
  281. // all the values to their defaults.
  282. VALIDATEPARM(hr, (cKeys == 0));
  283. if (FAILED(hr))
  284. {
  285. hr = NOERROR;
  286. goto doneValidate;
  287. }
  288. // read in the report value
  289. cb = sizeof(m_eedReport);
  290. dw = c_eedDefReport;
  291. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVDoReport, NULL,
  292. (PBYTE)&m_eedReport, &cb, (PBYTE)&dw, sizeof(dw),
  293. &iReport));
  294. if (FAILED(hr))
  295. goto done;
  296. // read in the ui value
  297. cb = sizeof(m_eedUI);
  298. dw = c_eedDefShowUI;
  299. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVShowUI, NULL,
  300. (PBYTE)&m_eedUI, &cb, (PBYTE)&dw, sizeof(dw),
  301. &iShowUI));
  302. if (FAILED(hr))
  303. goto done;
  304. // set the policy info (note that the policy key is always set into
  305. // slot 0 of the array)
  306. if (fHavePolicy)
  307. {
  308. if (iReport == 0)
  309. m_dwStatus |= REPORT_POLICY;
  310. if (iShowUI == 0)
  311. m_dwStatus |= SHOWUI_POLICY;
  312. ErrorTrace(0, " iReport = %d, iShowUI = %d", iReport, iShowUI);
  313. // if we used the default value for reporting (we didn't find the
  314. // 'report' value anywhere) then try to use the control panel settings
  315. // for the rest of the stuff.
  316. if (iReport == 2 && cKeys == 2)
  317. iReport = 1;
  318. // if THAT doesn't exist, just bail cuz all of the other values have
  319. // already been set to their defaults
  320. else if (iReport == 1 && cKeys == 1)
  321. goto doneValidate;
  322. // only use the key where we read the 'DoReport' value from. Don't care
  323. // what the other key has to say...
  324. if (iReport == 1)
  325. {
  326. HKEY hkeySwap = rghkeyCfg[0];
  327. rghkeyCfg[0] = rghkeyCfg[1];
  328. rghkeyCfg[1] = hkeySwap;
  329. DBG_MSG("POLICY and CPL controls INVERTED!!!");
  330. }
  331. cKeys = 1;
  332. }
  333. // read in the inclusion list value
  334. cb = sizeof(m_eieApps);
  335. dw = c_eieDefApps;
  336. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVAllNone, NULL,
  337. (PBYTE)&m_eieApps, &cb, (PBYTE)&dw, sizeof(dw)));
  338. if (FAILED(hr))
  339. goto done;
  340. // read in the inc MS value
  341. cb = sizeof(m_eieMS);
  342. dw = c_eieDefMSApps;
  343. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncMS, NULL,
  344. (PBYTE)&m_eieMS, &cb, (PBYTE)&dw, sizeof(dw)));
  345. if (FAILED(hr))
  346. goto done;
  347. // read in the inc Windows components
  348. cb = sizeof(m_eieWin);
  349. dw = c_eieDefWinComp;
  350. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncWinComp, NULL,
  351. (PBYTE)&m_eieWin, &cb, (PBYTE)&dw, sizeof(dw)));
  352. if (FAILED(hr))
  353. goto done;
  354. // read in the text log value
  355. cb = sizeof(m_eedTextLog);
  356. dw = c_eedDefTextLog;
  357. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVDoTextLog, NULL,
  358. (PBYTE)&m_eedTextLog, &cb, (PBYTE)&dw, sizeof(dw)));
  359. if (FAILED(hr))
  360. goto done;
  361. // read in the include kernel faults value
  362. cb = sizeof(m_eieKernel);
  363. dw = c_eieDefKernel;
  364. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncKernel, NULL,
  365. (PBYTE)&m_eieKernel, &cb, (PBYTE)&dw,
  366. sizeof(dw)));
  367. if (FAILED(hr))
  368. goto done;
  369. // read in the include shutdown errs value
  370. cb = sizeof(m_eieShutdown);
  371. dw = (m_fSrv) ? c_eieDefShutdownSrv : c_eieDefShutdown;
  372. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVIncShutdown, NULL,
  373. (PBYTE)&m_eieShutdown, &cb, (PBYTE)&dw,
  374. sizeof(dw)));
  375. if (FAILED(hr))
  376. goto done;
  377. // read in the # of fault pipes value
  378. cb = sizeof(m_cFaultPipes);
  379. dw = c_cDefFaultPipes;
  380. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVNumFaultPipe, NULL,
  381. (PBYTE)&m_cFaultPipes, &cb, (PBYTE)&dw,
  382. sizeof(dw)));
  383. if (FAILED(hr))
  384. goto done;
  385. // read in the # of hang pipes value
  386. cb = sizeof(m_cHangPipes);
  387. dw = c_cDefHangPipes;
  388. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVNumHangPipe, NULL,
  389. (PBYTE)&m_cHangPipes, &cb, (PBYTE)&dw,
  390. sizeof(dw)));
  391. if (FAILED(hr))
  392. goto done;
  393. // read in the max queue size value
  394. cb = sizeof(m_cMaxQueueItems);
  395. dw = c_cDefMaxUserQueue;
  396. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVMaxQueueSize, NULL,
  397. (PBYTE)&m_cMaxQueueItems, &cb, (PBYTE)&dw,
  398. sizeof(dw)));
  399. if (FAILED(hr))
  400. goto done;
  401. // read in the force queue mode value
  402. cb = sizeof(m_fForceQueue);
  403. dw = (m_fSrv) ? c_fForceQueueSrv : c_fForceQueue;
  404. TESTHR(hr, ReadRegEntry(rghkeyCfg, cKeys, c_wszRVForceQueue, NULL,
  405. (PBYTE)&m_fForceQueue, &cb, (PBYTE)&dw,
  406. sizeof(dw)));
  407. if (FAILED(hr))
  408. goto done;
  409. m_dwUseInternal=0;
  410. wcscpy(m_wszSrv, c_wszDefSrvE);
  411. // the dump path is stored in the DW reg key, so we need to try to
  412. // open it up. However, we only need this value if we're going
  413. // to go into headless mode
  414. if (m_eedReport == eedEnabled && m_eedUI == eedDisabled)
  415. {
  416. // if the cpl corp path is set, we can't let DW do any reporting...
  417. if ((m_dwStatus & REPORT_POLICY) == 0 &&
  418. (m_dwStatus & CPL_CORPPATH_SET) != 0 &&
  419. m_eedReport == eedEnabled)
  420. m_eedReport = eedDisabled;
  421. if (m_eedReport == eedEnabled)
  422. {
  423. TESTERR(hr, RegOpenKeyExW(rghkeyCfg[0], c_wszRKDW, 0, KEY_READ,
  424. &hkeyCfgDW));
  425. if (SUCCEEDED(hr))
  426. {
  427. // read in the dump path value
  428. cb = sizeof(m_wszDump);
  429. TESTHR(hr, ReadRegEntry(&hkeyCfgDW, 1, c_wszRVDumpPath, NULL,
  430. (PBYTE)m_wszDump, &cb, (PBYTE)&wch,
  431. sizeof(wch)));
  432. if (FAILED(hr))
  433. goto done;
  434. }
  435. }
  436. }
  437. // it's ok if these fail. The code below will correctly deal with the
  438. // situation...
  439. TESTHR(hr, OpenRegKey(rghkeyCfg[0], c_wszRKExList, dwOpt,
  440. &m_rgLists[epfltExclude].hkey));
  441. if (FAILED(hr))
  442. m_rgLists[epfltExclude].hkey = NULL;
  443. TESTHR(hr, OpenRegKey(rghkeyCfg[0], c_wszRKIncList, dwOpt,
  444. &m_rgLists[epfltInclude].hkey));
  445. if (FAILED(hr))
  446. m_rgLists[epfltInclude].hkey = NULL;
  447. hr = NOERROR;
  448. doneValidate:
  449. // validate the data we've read and reset the values to defaults if they
  450. // are outside of the allowable range of values
  451. if (m_eedUI != eedEnabled && m_eedUI != eedDisabled &&
  452. m_eedUI != eedEnabledNoCheck)
  453. m_eedUI = c_eedDefShowUI;
  454. if (m_eedReport != eedEnabled && m_eedReport != eedDisabled)
  455. m_eedReport = c_eedDefReport;
  456. if (m_eedTextLog != eedEnabled && m_eedTextLog != eedDisabled)
  457. m_eedTextLog = c_eedDefTextLog;
  458. if (m_eieApps != eieIncDisabled && m_eieApps != eieExDisabled &&
  459. m_eieApps != eieInclude && m_eieApps != eieExclude)
  460. m_eieApps = c_eieDefApps;
  461. if (m_eieMS != eieInclude && m_eieMS != eieExclude)
  462. m_eieMS = c_eieDefMSApps;
  463. if (m_eieKernel != eieInclude && m_eieKernel != eieExclude)
  464. m_eieKernel = c_eieDefKernel;
  465. if (m_eieShutdown != eieInclude && m_eieShutdown != eieExclude)
  466. m_eieShutdown = (m_fSrv) ? c_eieDefShutdownSrv : c_eieDefShutdown;
  467. if (m_eieWin != eieInclude && m_eieWin != eieExclude)
  468. m_eieWin = c_eieDefWinComp;
  469. if (m_dwUseInternal != 1 && m_dwUseInternal != 0)
  470. m_dwUseInternal = c_dwDefInternal;
  471. if (m_cFaultPipes < c_cMinPipes)
  472. m_cFaultPipes = c_cMinPipes;
  473. else if (m_cFaultPipes > c_cMaxPipes)
  474. m_cFaultPipes = c_cMaxPipes;
  475. if (m_cHangPipes == c_cMinPipes)
  476. m_cHangPipes = c_cMinPipes;
  477. else if (m_cHangPipes > c_cMaxPipes)
  478. m_cHangPipes = c_cMaxPipes;
  479. if (m_cMaxQueueItems > c_cMaxQueue)
  480. m_cMaxQueueItems = c_cMaxQueue;
  481. if (m_fForceQueue != c_fForceQueue && m_fForceQueue != c_fForceQueueSrv)
  482. m_fForceQueue = (m_fSrv) ? c_fForceQueueSrv : c_fForceQueue;
  483. m_fRead = TRUE;
  484. m_fRO = (ero != eroCPRW);
  485. aucs.Unlock();
  486. done:
  487. if (rghkeyCfg[0] != NULL)
  488. RegCloseKey(rghkeyCfg[0]);
  489. if (rghkeyCfg[1] != NULL)
  490. RegCloseKey(rghkeyCfg[1]);
  491. if (hkeyCfgDW != NULL)
  492. RegCloseKey(hkeyCfgDW);
  493. if (FAILED(hr))
  494. this->Clear();
  495. return hr;
  496. }
  497. #ifndef PFCLICFG_LITE
  498. // **************************************************************************
  499. BOOL CPFFaultClientCfg::HasWriteAccess(void)
  500. {
  501. USE_TRACING("CPFFaultClientCfg::HasWriteAccess");
  502. HRESULT hr = NOERROR;
  503. DWORD dwOpt = orkWantWrite;
  504. HKEY hkeyMain = NULL, hkey = NULL;
  505. // attempt to open all the keys we use for the control panal to see if we
  506. // have write access to them. We only do this for the control panal cuz
  507. // this class does not support writing out policy values, just reading
  508. // them...
  509. TESTHR(hr, OpenRegKey(HKEY_LOCAL_MACHINE, c_wszRPCfg, dwOpt, &hkeyMain));
  510. if (FAILED(hr))
  511. goto done;
  512. RegCloseKey(hkey);
  513. hkey = NULL;
  514. TESTHR(hr, OpenRegKey(hkeyMain, c_wszRKExList, dwOpt, &hkey));
  515. if (FAILED(hr))
  516. goto done;
  517. RegCloseKey(hkey);
  518. hkey = NULL;
  519. TESTHR(hr, OpenRegKey(hkeyMain, c_wszRKIncList, dwOpt, &hkey));
  520. if (FAILED(hr))
  521. goto done;
  522. done:
  523. if (hkeyMain != NULL)
  524. RegCloseKey(hkeyMain);
  525. if (hkey != NULL)
  526. RegCloseKey(hkey);
  527. return (SUCCEEDED(hr));
  528. }
  529. // **************************************************************************
  530. HRESULT CPFFaultClientCfg::Write(void)
  531. {
  532. USE_TRACING("CPFFaultClientCfg::Write");
  533. CAutoUnlockCS aucs(&m_cs);
  534. HRESULT hr = NOERROR;
  535. DWORD dwOpt = orkWantWrite;
  536. HKEY hkeyCfg = NULL;
  537. // this will automatically unlock when the fn exits
  538. aucs.Lock();
  539. if (m_fRO)
  540. {
  541. hr = E_ACCESSDENIED;
  542. goto done;
  543. }
  544. TESTHR(hr, OpenRegKey(HKEY_LOCAL_MACHINE, c_wszRPCfg, dwOpt, &hkeyCfg));
  545. if (FAILED(hr))
  546. goto done;
  547. // inclusion / exclusion list value
  548. if ((m_dwDirty & FHCC_ALLNONE) != 0)
  549. {
  550. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVAllNone, 0, REG_DWORD,
  551. (PBYTE)&m_eieApps, sizeof(m_eieApps)));
  552. if (FAILED(hr))
  553. goto done;
  554. m_dwDirty &= ~FHCC_ALLNONE;
  555. }
  556. // ms apps in except list value
  557. if ((m_dwDirty & FHCC_INCMS) != 0)
  558. {
  559. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncMS, 0, REG_DWORD,
  560. (PBYTE)&m_eieMS, sizeof(m_eieMS)));
  561. if (FAILED(hr))
  562. goto done;
  563. m_dwDirty &= ~FHCC_INCMS;
  564. }
  565. // ms apps in except list value
  566. if ((m_dwDirty & FHCC_WINCOMP) != 0)
  567. {
  568. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncWinComp, 0, REG_DWORD,
  569. (PBYTE)&m_eieWin, sizeof(m_eieWin)));
  570. if (FAILED(hr))
  571. goto done;
  572. m_dwDirty &= ~FHCC_WINCOMP;
  573. }
  574. // show UI value
  575. if ((m_dwDirty & FHCC_SHOWUI) != 0)
  576. {
  577. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVShowUI, 0, REG_DWORD,
  578. (PBYTE)&m_eedUI, sizeof(m_eedUI)));
  579. if (FAILED(hr))
  580. goto done;
  581. m_dwDirty &= ~FHCC_SHOWUI;
  582. }
  583. // do reporting value
  584. if ((m_dwDirty & FHCC_DOREPORT) != 0)
  585. {
  586. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVDoReport, 0, REG_DWORD,
  587. (PBYTE)&m_eedReport, sizeof(m_eedReport)));
  588. if (FAILED(hr))
  589. goto done;
  590. m_dwDirty &= ~FHCC_DOREPORT;
  591. }
  592. // include kernel faults value
  593. if ((m_dwDirty & FHCC_R0INCLUDE) != 0)
  594. {
  595. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncKernel, 0, REG_DWORD,
  596. (PBYTE)&m_eieKernel, sizeof(m_eieKernel)));
  597. if (FAILED(hr))
  598. goto done;
  599. m_dwDirty &= ~FHCC_R0INCLUDE;
  600. }
  601. // include shutdown value
  602. if ((m_dwDirty & FHCC_INCSHUTDOWN) != 0)
  603. {
  604. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVIncShutdown, 0, REG_DWORD,
  605. (PBYTE)&m_eieShutdown,
  606. sizeof(m_eieShutdown)));
  607. if (FAILED(hr))
  608. goto done;
  609. m_dwDirty &= ~FHCC_INCSHUTDOWN;
  610. }
  611. // # fault pipes value
  612. if ((m_dwDirty & FHCC_NUMFAULTPIPE) != 0)
  613. {
  614. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVNumFaultPipe, 0, REG_DWORD,
  615. (PBYTE)&m_cFaultPipes,
  616. sizeof(m_cFaultPipes)));
  617. if (FAILED(hr))
  618. goto done;
  619. m_dwDirty &= ~FHCC_NUMFAULTPIPE;
  620. }
  621. // # hang pipes value
  622. if ((m_dwDirty & FHCC_NUMHANGPIPE) != 0)
  623. {
  624. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVNumHangPipe, 0, REG_DWORD,
  625. (PBYTE)&m_cHangPipes,
  626. sizeof(m_cHangPipes)));
  627. if (FAILED(hr))
  628. goto done;
  629. m_dwDirty &= ~FHCC_NUMHANGPIPE;
  630. }
  631. // max user fault queue size value
  632. if ((m_dwDirty & FHCC_QUEUESIZE) != 0)
  633. {
  634. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVMaxQueueSize, 0, REG_DWORD,
  635. (PBYTE)&m_cMaxQueueItems,
  636. sizeof(m_cMaxQueueItems)));
  637. if (FAILED(hr))
  638. goto done;
  639. m_dwDirty &= ~FHCC_QUEUESIZE;
  640. }
  641. // default Server value
  642. if ((m_dwDirty & FHCC_DEFSRV) != 0)
  643. {
  644. DWORD cb;
  645. cb = wcslen(m_wszSrv) * sizeof(WCHAR);
  646. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVDefSrv, 0, REG_DWORD,
  647. (PBYTE)m_wszSrv, cb));
  648. if (FAILED(hr))
  649. goto done;
  650. m_dwDirty &= ~FHCC_DEFSRV;
  651. }
  652. // dump path value
  653. if ((m_dwDirty & FHCC_DUMPPATH) != 0)
  654. {
  655. DWORD cb;
  656. cb = wcslen(m_wszDump) * sizeof(WCHAR);
  657. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVDumpPath, 0, REG_DWORD,
  658. (PBYTE)m_wszDump, cb));
  659. if (FAILED(hr))
  660. goto done;
  661. m_dwDirty &= ~FHCC_DUMPPATH;
  662. }
  663. // force queue mode value
  664. if ((m_dwDirty & FHCC_FORCEQUEUE) != 0)
  665. {
  666. TESTERR(hr, RegSetValueExW(hkeyCfg, c_wszRVForceQueue, 0, REG_DWORD,
  667. (PBYTE)&m_fForceQueue,
  668. sizeof(m_fForceQueue)));
  669. if (FAILED(hr))
  670. goto done;
  671. m_dwDirty &= ~FHCC_FORCEQUEUE;
  672. }
  673. aucs.Unlock();
  674. done:
  675. if (hkeyCfg != NULL)
  676. RegCloseKey(hkeyCfg);
  677. return hr;
  678. }
  679. #endif // PFCLICFG_LITE
  680. // **************************************************************************
  681. BOOL CPFFaultClientCfg::ShouldCollect(LPWSTR wszAppPath, BOOL *pfIsMSApp)
  682. {
  683. USE_TRACING("CPFFaultClientCfg::ShouldCollect");
  684. CAutoUnlockCS aucs(&m_cs);
  685. HRESULT hr = NOERROR;
  686. WCHAR *pwszApp, wszName[MAX_PATH], wszAppPathLocal[MAX_PATH];
  687. DWORD i, cb, dwChecked, dw, dwMS, dwType;
  688. BOOL fCollect = FALSE;
  689. if (wszAppPath == NULL)
  690. {
  691. GetModuleFileNameW(NULL, wszAppPathLocal, sizeofSTRW(wszAppPathLocal));
  692. wszAppPath = wszAppPathLocal;
  693. }
  694. if (pfIsMSApp != NULL)
  695. *pfIsMSApp = FALSE;
  696. aucs.Lock();
  697. if (m_fRead == FALSE)
  698. {
  699. TESTHR(hr, this->Read());
  700. if (FAILED(hr))
  701. goto done;
  702. }
  703. // if we have reporting turned off or the 'programs' checkbox has been cleared
  704. // in the control panel, then we are definitely not reporting
  705. if (m_eedReport == eedDisabled || m_eieApps == eieExDisabled ||
  706. m_eieApps == eieIncDisabled)
  707. {
  708. fCollect = FALSE;
  709. goto done;
  710. }
  711. // get a pointer to the app name
  712. for (pwszApp = wszAppPath + wcslen(wszAppPath);
  713. *pwszApp != L'\\' && pwszApp != wszAppPath;
  714. pwszApp--);
  715. if (*pwszApp == L'\\')
  716. pwszApp++;
  717. // are we collecting everything by default?
  718. if (m_eieApps == eieInclude)
  719. fCollect = TRUE;
  720. if (fCollect == FALSE || pfIsMSApp != NULL)
  721. {
  722. // nope, check if it's another Microsoft app...
  723. dwMS = IsMicrosoftApp(wszAppPath, NULL, 0);
  724. if (dwMS != 0 && pfIsMSApp != NULL)
  725. *pfIsMSApp = TRUE;
  726. // is it a windows component?
  727. if (m_eieWin == eieInclude && (dwMS & APP_WINCOMP) != 0)
  728. fCollect = TRUE;
  729. // is it a MS app?
  730. if (m_eieMS == eieInclude && (dwMS & APP_MSAPP) != 0)
  731. fCollect = TRUE;
  732. }
  733. // see if it's on the inclusion list (only need to do this if we aren't
  734. // already collecting).
  735. // Note that if the value is not a DWORD key or we get back an error
  736. // saying that we don't have enuf space to hold the data, we just assume
  737. // that it should be included.
  738. if (fCollect == FALSE && m_rgLists[epfltInclude].hkey != NULL)
  739. {
  740. cb = sizeof(dwChecked);
  741. dwType = REG_DWORD;
  742. dw = RegQueryValueExW(m_rgLists[epfltInclude].hkey, pwszApp, NULL,
  743. &dwType, (PBYTE)&dwChecked, &cb);
  744. if ((dw == ERROR_SUCCESS &&
  745. (dwChecked == 1 || dwType != REG_DWORD)) ||
  746. dw == ERROR_MORE_DATA)
  747. fCollect = TRUE;
  748. }
  749. // see if it's on the exclusion list (only need to do this if we are going
  750. // to collect something)
  751. // Note that if the value is not a DWORD key or we get back an error
  752. // saying that we don't have enuf space to hold the data, we just assume
  753. // that it should be excluded.
  754. if (fCollect && m_rgLists[epfltExclude].hkey != NULL)
  755. {
  756. cb = sizeof(dwChecked);
  757. dwType = REG_DWORD;
  758. dw = RegQueryValueExW(m_rgLists[epfltExclude].hkey, pwszApp, NULL,
  759. &dwType, (PBYTE)&dwChecked, &cb);
  760. if ((dw == ERROR_SUCCESS &&
  761. (dwChecked == 1 || dwType != REG_DWORD)) ||
  762. dw == ERROR_MORE_DATA)
  763. fCollect = FALSE;
  764. }
  765. done:
  766. return fCollect;
  767. }
  768. /////////////////////////////////////////////////////////////////////////////
  769. // CPFFaultClientCfg- get properties
  770. // **************************************************************************
  771. static inline LPCWSTR get_string(LPWSTR wszOut, LPWSTR wszSrc, int cchOut)
  772. {
  773. LPCWSTR wszRet;
  774. SetLastError(0);
  775. if (wszOut == NULL)
  776. {
  777. wszRet = wszSrc;
  778. }
  779. else
  780. {
  781. wszRet = wszOut;
  782. if (cchOut < lstrlenW(wszSrc))
  783. {
  784. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  785. return NULL;
  786. }
  787. lstrcpyW(wszOut, wszSrc);
  788. }
  789. return wszRet;
  790. }
  791. // **************************************************************************
  792. LPCWSTR CPFFaultClientCfg::get_DumpPath(LPWSTR wsz, int cch)
  793. {
  794. USE_TRACING("CPFFaultClientCfg::get_DumpPath");
  795. CAutoUnlockCS aucs(&m_cs);
  796. aucs.Lock();
  797. return get_string(wsz, m_wszDump, cch);
  798. }
  799. // **************************************************************************
  800. LPCWSTR CPFFaultClientCfg::get_DefaultServer(LPWSTR wsz, int cch)
  801. {
  802. USE_TRACING("CPFFaultClientCfg::get_DefaultServer");
  803. CAutoUnlockCS aucs(&m_cs);
  804. aucs.Lock();
  805. return get_string(wsz, m_wszSrv, cch);
  806. }
  807. #ifndef PFCLICFG_LITE
  808. /////////////////////////////////////////////////////////////////////////////
  809. // CPFFaultClientCfg- set properties
  810. // **************************************************************************
  811. BOOL CPFFaultClientCfg::set_DumpPath(LPCWSTR wsz)
  812. {
  813. USE_TRACING("CPFFaultClientCfg::set_DumpPath");
  814. CAutoUnlockCS aucs(&m_cs);
  815. if (wsz == NULL ||
  816. (wcslen(wsz) + 1) > sizeofSTRW(m_wszDump))
  817. {
  818. SetLastError(ERROR_INVALID_PARAMETER);
  819. return FALSE;
  820. }
  821. aucs.Lock();
  822. wcscpy(m_wszDump, wsz);
  823. m_dwDirty |= FHCC_DUMPPATH;
  824. return TRUE;
  825. }
  826. // **************************************************************************
  827. BOOL CPFFaultClientCfg::set_DefaultServer(LPCWSTR wsz)
  828. {
  829. USE_TRACING("CPFFaultClientCfg::set_DefaultServer");
  830. CAutoUnlockCS aucs(&m_cs);
  831. if (wsz == NULL ||
  832. (wcslen(wsz) + 1) > sizeofSTRW(m_wszSrv))
  833. {
  834. SetLastError(ERROR_INVALID_PARAMETER);
  835. return FALSE;
  836. }
  837. aucs.Lock();
  838. wcscpy(m_wszSrv, wsz);
  839. m_dwDirty |= FHCC_DEFSRV;
  840. return TRUE;
  841. }
  842. // **************************************************************************
  843. BOOL CPFFaultClientCfg::set_ShowUI(EEnDis eed)
  844. {
  845. USE_TRACING("CPFFaultClientCfg::set_ShowUI");
  846. CAutoUnlockCS aucs(&m_cs);
  847. if (eed & ~1 && (DWORD)eed != 3)
  848. {
  849. SetLastError(ERROR_INVALID_PARAMETER);
  850. return FALSE;
  851. }
  852. aucs.Lock();
  853. m_eedUI = eed;
  854. m_dwDirty |= FHCC_SHOWUI;
  855. return TRUE;
  856. }
  857. // **************************************************************************
  858. BOOL CPFFaultClientCfg::set_DoReport(EEnDis eed)
  859. {
  860. USE_TRACING("CPFFaultClientCfg::set_DoReport");
  861. CAutoUnlockCS aucs(&m_cs);
  862. if (eed & ~1)
  863. {
  864. SetLastError(ERROR_INVALID_PARAMETER);
  865. return FALSE;
  866. }
  867. aucs.Lock();
  868. m_eedReport = eed;
  869. m_dwDirty |= FHCC_DOREPORT;
  870. return TRUE;
  871. }
  872. // **************************************************************************
  873. BOOL CPFFaultClientCfg::set_AllOrNone(EIncEx eie)
  874. {
  875. USE_TRACING("CPFFaultClientCfg::set_AllOrNone");
  876. CAutoUnlockCS aucs(&m_cs);
  877. if (eie & ~3)
  878. {
  879. SetLastError(ERROR_INVALID_PARAMETER);
  880. return FALSE;
  881. }
  882. aucs.Lock();
  883. m_eieApps = eie;
  884. m_dwDirty |= FHCC_ALLNONE;
  885. return TRUE;
  886. }
  887. // **************************************************************************
  888. BOOL CPFFaultClientCfg::set_IncMSApps(EIncEx eie)
  889. {
  890. USE_TRACING("CPFFaultClientCfg::set_IncMSApps");
  891. CAutoUnlockCS aucs(&m_cs);
  892. if (eie & ~1)
  893. {
  894. SetLastError(ERROR_INVALID_PARAMETER);
  895. return FALSE;
  896. }
  897. aucs.Lock();
  898. m_eieMS = eie;
  899. m_dwDirty |= FHCC_INCMS;
  900. return TRUE;
  901. }
  902. // **************************************************************************
  903. BOOL CPFFaultClientCfg::set_IncWinComp(EIncEx eie)
  904. {
  905. USE_TRACING("CPFFaultClientCfg::set_IncWinComp");
  906. CAutoUnlockCS aucs(&m_cs);
  907. if (eie & ~1)
  908. {
  909. SetLastError(ERROR_INVALID_PARAMETER);
  910. return FALSE;
  911. }
  912. aucs.Lock();
  913. m_eieWin = eie;
  914. m_dwDirty |= FHCC_WINCOMP;
  915. return TRUE;
  916. }
  917. // **************************************************************************
  918. BOOL CPFFaultClientCfg::set_IncKernel(EIncEx eie)
  919. {
  920. USE_TRACING("CPFFaultClientCfg::set_IncKernel");
  921. CAutoUnlockCS aucs(&m_cs);
  922. if (eie & ~1)
  923. {
  924. SetLastError(ERROR_INVALID_PARAMETER);
  925. return FALSE;
  926. }
  927. aucs.Lock();
  928. m_eieKernel = eie;
  929. m_dwDirty |= FHCC_R0INCLUDE;
  930. return TRUE;
  931. }
  932. // **************************************************************************
  933. BOOL CPFFaultClientCfg::set_IncShutdown(EIncEx eie)
  934. {
  935. USE_TRACING("CPFFaultClientCfg::set_IncShutdown");
  936. CAutoUnlockCS aucs(&m_cs);
  937. if (eie & ~1)
  938. {
  939. SetLastError(ERROR_INVALID_PARAMETER);
  940. return FALSE;
  941. }
  942. aucs.Lock();
  943. m_eieShutdown = eie;
  944. m_dwDirty |= FHCC_INCSHUTDOWN;
  945. return TRUE;
  946. }
  947. // **************************************************************************
  948. BOOL CPFFaultClientCfg::set_ForceQueueMode(BOOL fForceQueueMode)
  949. {
  950. USE_TRACING("CPFFaultClientCfg::set_IncKernel");
  951. CAutoUnlockCS aucs(&m_cs);
  952. if (fForceQueueMode & ~1)
  953. {
  954. SetLastError(ERROR_INVALID_PARAMETER);
  955. return FALSE;
  956. }
  957. aucs.Lock();
  958. m_fForceQueue = fForceQueueMode;
  959. m_dwDirty |= FHCC_FORCEQUEUE;
  960. return TRUE;
  961. }
  962. // **************************************************************************
  963. BOOL CPFFaultClientCfg::set_NumFaultPipes(DWORD cPipes)
  964. {
  965. USE_TRACING("CPFFaultClientCfg::set_NumFaultPipes");
  966. CAutoUnlockCS aucs(&m_cs);
  967. if (cPipes == 0 || cPipes > 8)
  968. {
  969. SetLastError(ERROR_INVALID_PARAMETER);
  970. return FALSE;
  971. }
  972. aucs.Lock();
  973. m_cFaultPipes = cPipes;
  974. m_dwDirty |= FHCC_NUMFAULTPIPE;
  975. return TRUE;
  976. }
  977. // **************************************************************************
  978. BOOL CPFFaultClientCfg::set_NumHangPipes(DWORD cPipes)
  979. {
  980. USE_TRACING("CPFFaultClientCfg::set_NumHangPipes");
  981. CAutoUnlockCS aucs(&m_cs);
  982. if (cPipes == 0 || cPipes > 8)
  983. {
  984. SetLastError(ERROR_INVALID_PARAMETER);
  985. return FALSE;
  986. }
  987. aucs.Lock();
  988. m_cHangPipes = cPipes;
  989. m_dwDirty |= FHCC_NUMHANGPIPE;
  990. return TRUE;
  991. }
  992. // **************************************************************************
  993. BOOL CPFFaultClientCfg::set_MaxUserQueueSize(DWORD cItems)
  994. {
  995. USE_TRACING("CPFFaultClientCfg::set_MaxUserQueueSize");
  996. CAutoUnlockCS aucs(&m_cs);
  997. if (cItems == 0 || cItems > 256)
  998. {
  999. SetLastError(ERROR_INVALID_PARAMETER);
  1000. return FALSE;
  1001. }
  1002. aucs.Lock();
  1003. m_cMaxQueueItems = cItems;
  1004. m_dwDirty |= FHCC_QUEUESIZE;
  1005. return TRUE;
  1006. }
  1007. /////////////////////////////////////////////////////////////////////////////
  1008. // App lists
  1009. // **************************************************************************
  1010. HRESULT CPFFaultClientCfg::InitList(EPFListType epflt)
  1011. {
  1012. USE_TRACING("CPFFaultClientCfg::get_IncListCount");
  1013. CAutoUnlockCS aucs(&m_cs);
  1014. HRESULT hr = NOERROR;
  1015. DWORD cItems = 0;
  1016. VALIDATEPARM(hr, (epflt >= epfltListCount));
  1017. if (FAILED(hr))
  1018. goto done;
  1019. aucs.Lock();
  1020. if (m_fRead == FALSE)
  1021. {
  1022. hr = E_FAIL;
  1023. goto done;;
  1024. }
  1025. // if we've already initialized, then just clear the list out & return
  1026. if ((m_rgLists[epflt].dwState & epfaaInitialized) != 0)
  1027. {
  1028. this->ClearChanges(epflt);
  1029. m_rgLists[epflt].dwState &= ~epfaaInitialized;
  1030. }
  1031. if (m_rgLists[epflt].hkey != NULL)
  1032. {
  1033. TESTERR(hr, RegQueryInfoKeyW(m_rgLists[epflt].hkey, NULL, NULL, NULL,
  1034. NULL, NULL, NULL,
  1035. &m_rgLists[epflt].cItemsInReg,
  1036. &m_rgLists[epflt].cchMaxVal, NULL, NULL,
  1037. NULL));
  1038. if (FAILED(hr))
  1039. goto done;
  1040. }
  1041. else
  1042. {
  1043. m_rgLists[epflt].cItemsInReg = 0;
  1044. m_rgLists[epflt].cchMaxVal = 0;
  1045. }
  1046. m_rgLists[epflt].dwState |= epfaaInitialized;
  1047. done:
  1048. return hr;
  1049. }
  1050. // **************************************************************************
  1051. HRESULT CPFFaultClientCfg::get_ListRegInfo(EPFListType epflt, DWORD *pcbMaxName,
  1052. DWORD *pcApps)
  1053. {
  1054. USE_TRACING("CPFFaultClientCfg::get_ListRegInfo");
  1055. CAutoUnlockCS aucs(&m_cs);
  1056. HRESULT hr = NOERROR;
  1057. VALIDATEPARM(hr, (pcbMaxName == NULL || pcApps == NULL ||
  1058. epflt >= epfltListCount));
  1059. if (FAILED(hr))
  1060. goto done;
  1061. aucs.Lock();
  1062. *pcbMaxName = 0;
  1063. *pcApps = 0;
  1064. if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0)
  1065. {
  1066. hr = E_FAIL;
  1067. goto done;
  1068. }
  1069. *pcbMaxName = m_rgLists[epflt].cchMaxVal;
  1070. *pcApps = m_rgLists[epflt].cItemsInReg;
  1071. done:
  1072. return hr;
  1073. }
  1074. // **************************************************************************
  1075. HRESULT CPFFaultClientCfg::get_ListRegApp(EPFListType epflt, DWORD iApp,
  1076. LPWSTR wszApp, DWORD cchApp,
  1077. DWORD *pdwChecked)
  1078. {
  1079. USE_TRACING("CPFFaultClientCfg::get_ListApp");
  1080. CAutoUnlockCS aucs(&m_cs);
  1081. HRESULT hr = NOERROR;
  1082. WCHAR wsz[MAX_PATH];
  1083. DWORD cchName, cbData, dw, dwType = 0;
  1084. VALIDATEPARM(hr, (wszApp == NULL || pdwChecked == NULL ||
  1085. epflt >= epfltListCount));
  1086. if (FAILED(hr))
  1087. goto done;
  1088. *wszApp = L'\0';
  1089. *pdwChecked = 0;
  1090. aucs.Lock();
  1091. if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0)
  1092. {
  1093. hr = E_FAIL;
  1094. goto done;
  1095. }
  1096. cchName = cchApp;
  1097. cbData = sizeof(DWORD);
  1098. dw = RegEnumValueW(m_rgLists[epflt].hkey, iApp, wszApp, &cchName, NULL,
  1099. &dwType, (LPBYTE)pdwChecked, &cbData);
  1100. if (dw != ERROR_SUCCESS && dw != ERROR_NO_MORE_ITEMS)
  1101. {
  1102. if (dw == ERROR_MORE_DATA)
  1103. {
  1104. dw = RegEnumValueW(m_rgLists[epflt].hkey, iApp, wszApp, &cchName,
  1105. NULL, NULL, NULL, NULL);
  1106. *pdwChecked = 1;
  1107. }
  1108. TESTERR(hr, dw);
  1109. goto done;
  1110. }
  1111. if (dwType != REG_DWORD || (*pdwChecked != 1 && *pdwChecked != 0))
  1112. *pdwChecked = 1;
  1113. if (dw == ERROR_NO_MORE_ITEMS)
  1114. {
  1115. hr = S_FALSE;
  1116. goto done;
  1117. }
  1118. done:
  1119. return hr;
  1120. }
  1121. // **************************************************************************
  1122. HRESULT CPFFaultClientCfg::add_ListApp(EPFListType epflt, LPCWSTR wszApp)
  1123. {
  1124. USE_TRACING("CPFFaultClientCfg::add_ListApp");
  1125. CAutoUnlockCS aucs(&m_cs);
  1126. SAppItem sai;
  1127. HRESULT hr = NOERROR;
  1128. LPWSTR wszExe = NULL;
  1129. DWORD dw = 0, i;
  1130. VALIDATEPARM(hr, (wszApp == NULL || epflt >= epfltListCount));
  1131. if (FAILED(hr))
  1132. goto done;
  1133. aucs.Lock();
  1134. if (m_fRO == TRUE)
  1135. {
  1136. hr = E_ACCESSDENIED;
  1137. goto done;
  1138. }
  1139. if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0)
  1140. {
  1141. hr = E_FAIL;
  1142. goto done;
  1143. }
  1144. // first, check if it's already on the mod list
  1145. for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++)
  1146. {
  1147. if (m_rgLists[epflt].rgsai[i].wszApp != NULL &&
  1148. _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0)
  1149. {
  1150. SETADD(m_rgLists[epflt].rgsai[i].dwState);
  1151. SETCHECK(m_rgLists[epflt].rgsai[i].dwState);
  1152. goto done;
  1153. }
  1154. }
  1155. // add it to the list then...
  1156. wszExe = (LPWSTR)MyAlloc((wcslen(wszApp) + 1) * sizeof(WCHAR));
  1157. VALIDATEEXPR(hr, (wszExe == NULL), E_OUTOFMEMORY);
  1158. if (FAILED(hr))
  1159. goto done;
  1160. wcscpy(wszExe, wszApp);
  1161. sai.wszApp = wszExe;
  1162. SETADD(sai.dwState);
  1163. SETCHECK(sai.dwState);
  1164. TESTHR(hr, AddToArray(m_rgLists[epflt], &sai));
  1165. if (FAILED(hr))
  1166. goto done;
  1167. wszExe = NULL;
  1168. done:
  1169. if (wszExe != NULL)
  1170. MyFree(wszExe);
  1171. return hr;
  1172. }
  1173. // **************************************************************************
  1174. HRESULT CPFFaultClientCfg::del_ListApp(EPFListType epflt, LPWSTR wszApp)
  1175. {
  1176. USE_TRACING("CPFFaultClientCfg::del_ListApp");
  1177. CAutoUnlockCS aucs(&m_cs);
  1178. SAppItem sai;
  1179. HRESULT hr = NOERROR;
  1180. LPWSTR wszExe = NULL;
  1181. DWORD i;
  1182. VALIDATEPARM(hr, (wszApp == NULL || epflt >= epfltListCount));
  1183. if (FAILED(hr))
  1184. goto done;
  1185. aucs.Lock();
  1186. if (m_fRO == TRUE)
  1187. {
  1188. hr = E_ACCESSDENIED;
  1189. goto done;
  1190. }
  1191. // first, check if it's already on the mod list for add
  1192. for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++)
  1193. {
  1194. if (m_rgLists[epflt].rgsai[i].wszApp != NULL &&
  1195. _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0)
  1196. {
  1197. if (m_rgLists[epflt].rgsai[i].dwState & epfaaAdd)
  1198. {
  1199. // just set the wszApp field to NULL. we'll reuse it
  1200. // on the next add to the array (if any)
  1201. MyFree(m_rgLists[epflt].rgsai[i].wszApp);
  1202. m_rgLists[epflt].rgsai[i].wszApp = NULL;
  1203. m_rgLists[epflt].rgsai[i].dwState = 0;
  1204. m_rgLists[epflt].cSlotsEmpty++;
  1205. }
  1206. else
  1207. {
  1208. SETDEL(m_rgLists[epflt].rgsai[i].dwState);
  1209. }
  1210. goto done;
  1211. }
  1212. }
  1213. // add it to the list then...
  1214. wszExe = (LPWSTR)MyAlloc((wcslen(wszApp) + 1) * sizeof(WCHAR));
  1215. VALIDATEEXPR(hr, (wszExe == NULL), E_OUTOFMEMORY);
  1216. if (FAILED(hr))
  1217. goto done;
  1218. wcscpy(wszExe, wszApp);
  1219. sai.wszApp = wszExe;
  1220. SETDEL(sai.dwState);
  1221. TESTHR(hr, AddToArray(m_rgLists[epflt], &sai));
  1222. if (FAILED(hr))
  1223. goto done;
  1224. wszExe = NULL;
  1225. done:
  1226. if (wszExe != NULL)
  1227. MyFree(wszExe);
  1228. return hr;
  1229. }
  1230. // **************************************************************************
  1231. HRESULT CPFFaultClientCfg::mod_ListApp(EPFListType epflt, LPWSTR wszApp,
  1232. DWORD dwChecked)
  1233. {
  1234. USE_TRACING("CPFFaultClientCfg::del_ListApp");
  1235. CAutoUnlockCS aucs(&m_cs);
  1236. SAppItem sai;
  1237. HRESULT hr = NOERROR;
  1238. LPWSTR wszExe = NULL;
  1239. DWORD i;
  1240. VALIDATEPARM(hr, (wszApp == NULL || epflt >= epfltListCount));
  1241. if (FAILED(hr))
  1242. goto done;
  1243. aucs.Lock();
  1244. if (m_fRO == TRUE)
  1245. {
  1246. hr = E_ACCESSDENIED;
  1247. goto done;
  1248. }
  1249. // first, check if it's already on the mod list
  1250. for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++)
  1251. {
  1252. if (m_rgLists[epflt].rgsai[i].wszApp != NULL &&
  1253. _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0)
  1254. {
  1255. if (dwChecked == 0)
  1256. {
  1257. REMCHECK(m_rgLists[epflt].rgsai[i].dwState);
  1258. }
  1259. else
  1260. {
  1261. SETCHECK(m_rgLists[epflt].rgsai[i].dwState);
  1262. }
  1263. goto done;
  1264. }
  1265. }
  1266. // add it to the list then...
  1267. wszExe = (LPWSTR)MyAlloc((wcslen(wszApp) + 1) * sizeof(WCHAR));
  1268. VALIDATEEXPR(hr, (wszExe == NULL), E_OUTOFMEMORY);
  1269. if (FAILED(hr))
  1270. goto done;
  1271. wcscpy(wszExe, wszApp);
  1272. sai.wszApp = wszExe;
  1273. sai.dwState = ((dwChecked == 0) ? epfaaRemCheck : epfaaSetCheck);
  1274. TESTHR(hr, AddToArray(m_rgLists[epflt], &sai));
  1275. if (FAILED(hr))
  1276. goto done;
  1277. wszExe = NULL;
  1278. done:
  1279. if (wszExe != NULL)
  1280. MyFree(wszExe);
  1281. return hr;
  1282. }
  1283. // **************************************************************************
  1284. HRESULT CPFFaultClientCfg::ClearChanges(EPFListType epflt)
  1285. {
  1286. USE_TRACING("CPFFaultClientCfg::ClearChanges");
  1287. CAutoUnlockCS aucs(&m_cs);
  1288. HRESULT hr = NOERROR;
  1289. DWORD i;
  1290. VALIDATEPARM(hr, (epflt >= epfltListCount));
  1291. if (FAILED(hr))
  1292. goto done;
  1293. aucs.Lock();
  1294. if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0)
  1295. {
  1296. hr = E_FAIL;
  1297. goto done;
  1298. }
  1299. if (m_rgLists[epflt].rgsai == NULL)
  1300. goto done;
  1301. for(i = 0; i < m_rgLists[epflt].cSlotsUsed; i++)
  1302. {
  1303. m_rgLists[epflt].rgsai[i].dwState = 0;
  1304. if (m_rgLists[epflt].rgsai[i].wszApp != NULL)
  1305. {
  1306. MyFree(m_rgLists[epflt].rgsai[i].wszApp);
  1307. m_rgLists[epflt].rgsai[i].wszApp = NULL;
  1308. }
  1309. }
  1310. m_rgLists[epflt].cSlotsUsed = 0;
  1311. done:
  1312. return hr;
  1313. }
  1314. // **************************************************************************
  1315. HRESULT CPFFaultClientCfg::CommitChanges(EPFListType epflt)
  1316. {
  1317. USE_TRACING("CPFFaultClientCfg::CommitChanges");
  1318. CAutoUnlockCS aucs(&m_cs);
  1319. HRESULT hr = NOERROR;
  1320. DWORD i, dw;
  1321. VALIDATEPARM(hr, (epflt >= epfltListCount));
  1322. if (FAILED(hr))
  1323. goto done;
  1324. aucs.Lock();
  1325. if (m_fRO == TRUE)
  1326. {
  1327. hr = E_ACCESSDENIED;
  1328. goto done;
  1329. }
  1330. if (m_fRead == FALSE || (m_rgLists[epflt].dwState & epfaaInitialized) == 0)
  1331. {
  1332. hr = E_FAIL;
  1333. goto done;
  1334. }
  1335. if (m_rgLists[epflt].hkey == NULL)
  1336. {
  1337. hr = E_ACCESSDENIED;
  1338. goto done;
  1339. }
  1340. if (m_rgLists[epflt].rgsai == NULL)
  1341. goto done;
  1342. // don't need to compress the array. Since we always append & never
  1343. // delete out of the array until a commit, once I hit an 'Add', anything
  1344. // after that in the array MUST also be an 'Add'.
  1345. for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++)
  1346. {
  1347. if (m_rgLists[epflt].rgsai[i].wszApp == NULL)
  1348. {
  1349. m_rgLists[epflt].rgsai[i].dwState = 0;
  1350. continue;
  1351. }
  1352. if ((m_rgLists[epflt].rgsai[i].dwState & epfaaDelete) != 0)
  1353. {
  1354. dw = RegDeleteValueW(m_rgLists[epflt].hkey,
  1355. m_rgLists[epflt].rgsai[i].wszApp);
  1356. if (dw != ERROR_SUCCESS && dw != ERROR_FILE_NOT_FOUND)
  1357. {
  1358. TESTERR(hr, dw);
  1359. goto done;
  1360. }
  1361. }
  1362. else
  1363. {
  1364. DWORD dwChecked;
  1365. dwChecked = (ISCHECKED(m_rgLists[epflt].rgsai[i].dwState)) ? 1 : 0;
  1366. TESTERR(hr, RegSetValueExW(m_rgLists[epflt].hkey,
  1367. m_rgLists[epflt].rgsai[i].wszApp, 0,
  1368. REG_DWORD, (LPBYTE)&dwChecked,
  1369. sizeof(DWORD)));
  1370. if (FAILED(hr))
  1371. goto done;
  1372. }
  1373. MyFree(m_rgLists[epflt].rgsai[i].wszApp);
  1374. m_rgLists[epflt].rgsai[i].wszApp = NULL;
  1375. m_rgLists[epflt].rgsai[i].dwState = 0;
  1376. }
  1377. m_rgLists[epflt].cSlotsUsed = 0;
  1378. done:
  1379. return hr;
  1380. }
  1381. // **************************************************************************
  1382. BOOL CPFFaultClientCfg::IsOnList(EPFListType epflt, LPCWSTR wszApp)
  1383. {
  1384. USE_TRACING("CPFFaultClientCfg::IsOnList");
  1385. SAppList *psap;
  1386. HRESULT hr = NOERROR;
  1387. DWORD i;
  1388. HKEY hkey = NULL;
  1389. VALIDATEPARM(hr, (epflt >= epfltListCount || wszApp == NULL));
  1390. if (FAILED(hr))
  1391. goto done;
  1392. if ((m_rgLists[epflt].dwState & epfaaInitialized) == 0)
  1393. {
  1394. hr = E_FAIL;
  1395. goto done;
  1396. }
  1397. // first, check the mod list. This is because if we check the registry
  1398. // first, we miss the case where the user just deleted it and it's
  1399. // therefore sitting in the mod list
  1400. hr = S_FALSE;
  1401. for (i = 0; i < m_rgLists[epflt].cSlotsUsed; i++)
  1402. {
  1403. if (m_rgLists[epflt].rgsai[i].wszApp != NULL &&
  1404. _wcsicmp(m_rgLists[epflt].rgsai[i].wszApp, wszApp) == 0)
  1405. {
  1406. if ((m_rgLists[epflt].rgsai[i].dwState & epfaaDelete) == 0)
  1407. hr = NOERROR;
  1408. goto done;
  1409. }
  1410. }
  1411. // next, check the registry.
  1412. TESTERR(hr, RegQueryValueExW(m_rgLists[epflt].hkey, wszApp, NULL, NULL,
  1413. NULL, NULL));
  1414. if (SUCCEEDED(hr))
  1415. goto done;
  1416. done:
  1417. return (hr == NOERROR);
  1418. }
  1419. #endif PFCLICFG_LITE