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

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