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.

1156 lines
31 KiB

  1. #include "precomp.h"
  2. #include "rsopsec.h"
  3. #include <regapix.h> // MAXIMUM_SUB_KEY_LENGTH, MAXIMUM_VALUE_NAME_LENGTH, MAXIMUM_DATA_LENGTH
  4. // TREE_TYPE
  5. #define TREE_UNKNOWN 0
  6. #define TREE_NEITHER 1
  7. #define TREE_CHECKBOX 2
  8. #define TREE_GROUP 3
  9. #define TREE_RADIO 4
  10. const struct
  11. {
  12. DWORD type; // TREE_TYPE
  13. LPCTSTR name;
  14. } c_aTreeTypes[] =
  15. {
  16. {TREE_CHECKBOX, TEXT("checkbox")},
  17. {TREE_RADIO, TEXT("radio")},
  18. {TREE_GROUP, TEXT("group")}
  19. };
  20. const TCHAR c_szType[] = TEXT("Type");
  21. const TCHAR c_szText[] = TEXT("Text");
  22. const TCHAR c_szPlugUIText[] = TEXT("PlugUIText");
  23. const TCHAR c_szDefaultBitmap[] = TEXT("Bitmap");
  24. const TCHAR c_szHKeyRoot[] = TEXT("HKeyRoot");
  25. const TCHAR c_szValueName[] = TEXT("ValueName");
  26. const TCHAR c_szCheckedValue[] = TEXT("CheckedValue");
  27. //const TCHAR c_szUncheckedValue[] = TEXT("UncheckedValue");
  28. const TCHAR c_szDefaultValue[] = TEXT("DefaultValue");
  29. //const TCHAR c_szSPIAction[] = TEXT("SPIAction");
  30. //const TCHAR c_szSPIParamON[] = TEXT("SPIParamON");
  31. //const TCHAR c_szSPIParamOFF[] = TEXT("SPIParamOFF");
  32. const TCHAR c_szCheckedValueNT[] = TEXT("CheckedValueNT");
  33. const TCHAR c_szCheckedValueW95[] = TEXT("CheckedValueW95");
  34. const TCHAR c_szMask[] = TEXT("Mask");
  35. const TCHAR c_szOffset[] = TEXT("Offset");
  36. //const TCHAR c_szHelpID[] = TEXT("HelpID");
  37. const TCHAR c_szWarning[] = TEXT("WarningIfNotDefault");
  38. // REG_CMD
  39. #define REG_GETDEFAULT 1
  40. #define REG_GET 2
  41. #define REG_SET 3
  42. // WALK_TREE_CMD
  43. #define WALK_TREE_DELETE 1
  44. #define WALK_TREE_RESTORE 2
  45. #define WALK_TREE_REFRESH 3
  46. #define IDCHECKED 0
  47. #define IDUNCHECKED 1
  48. #define IDRADIOON 2
  49. #define IDRADIOOFF 3
  50. #define IDUNKNOWN 4
  51. #define BITMAP_WIDTH 16
  52. #define BITMAP_HEIGHT 16
  53. #define NUM_BITMAPS 5
  54. #define MAX_KEY_NAME 64
  55. #define MAX_URL_STRING INTERNET_MAX_URL_LENGTH
  56. BOOL g_fNashInNewProcess = FALSE; // Are we running in a separate process
  57. BOOL g_fRunningOnNT = FALSE;
  58. BOOL g_bRunOnNT5 = FALSE;
  59. BOOL g_fRunOnWhistler = FALSE;
  60. BOOL g_bRunOnMemphis = FALSE;
  61. BOOL g_fRunOnFE = FALSE;
  62. DWORD g_dwStopWatchMode = 0; // Shell perf automation
  63. HKEY g_hkeyExplorer = NULL; // for SHGetExplorerHKey() in util.cpp
  64. HANDLE g_hCabStateChange = NULL;
  65. BOOL g_fIE = FALSE;
  66. ///////////////////////////////////////////////////////////////////////////////
  67. static int __cdecl CompareActionSettingStrings(const void *arg1, const void *arg2)
  68. {
  69. int iRet = 0;
  70. __try
  71. {
  72. iRet = StrCmp(((ACTION_SETTING *)arg1)->szName, ((ACTION_SETTING *)arg2)->szName );
  73. }
  74. __except(TRUE)
  75. {
  76. ASSERT(0);
  77. }
  78. return iRet;
  79. }
  80. //////////////////////////////////////////////////////////////////////////////
  81. //
  82. // CRegTreeOptions Object
  83. //
  84. //////////////////////////////////////////////////////////////////////////////
  85. CRegTreeOptions::CRegTreeOptions() :
  86. m_nASCount(0)
  87. {
  88. // cRef = 1;
  89. }
  90. CRegTreeOptions::~CRegTreeOptions()
  91. {
  92. // ASSERT(cRef == 0); // should always have zero
  93. // Str_SetPtr(&_pszParam, NULL);
  94. }
  95. /////////////////////////////////////////////////////////////////////
  96. BOOL IsScreenReaderEnabled()
  97. {
  98. BOOL bRet = FALSE;
  99. SystemParametersInfoA(SPI_GETSCREENREADER, 0, &bRet, 0);
  100. return bRet;
  101. }
  102. /////////////////////////////////////////////////////////////////////
  103. BOOL CRegTreeOptions::WalkTreeRecursive(HTREEITEM htvi, WALK_TREE_CMD cmd)
  104. {
  105. HTREEITEM hctvi; // child
  106. TV_ITEM tvi;
  107. HKEY hkey;
  108. BOOL bChecked;
  109. // step through the children
  110. hctvi = TreeView_GetChild( m_hwndTree, htvi );
  111. while ( hctvi )
  112. {
  113. WalkTreeRecursive(hctvi, cmd);
  114. hctvi = TreeView_GetNextSibling( m_hwndTree, hctvi );
  115. }
  116. // get ourselves
  117. tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  118. tvi.hItem = htvi;
  119. TreeView_GetItem( m_hwndTree, &tvi );
  120. switch (cmd)
  121. {
  122. case WALK_TREE_DELETE:
  123. // if we are destroying the tree...
  124. // do we have something to clean up?
  125. if ( tvi.lParam )
  126. {
  127. // close the reg hey
  128. RegCloseKey((HKEY)tvi.lParam);
  129. }
  130. break;
  131. case WALK_TREE_RESTORE:
  132. case WALK_TREE_REFRESH:
  133. hkey = (HKEY)tvi.lParam;
  134. bChecked = FALSE;
  135. if ((tvi.iImage == IDCHECKED) ||
  136. (tvi.iImage == IDUNCHECKED) ||
  137. (tvi.iImage == IDRADIOON) ||
  138. (tvi.iImage == IDRADIOOFF))
  139. {
  140. GetCheckStatus(hkey, &bChecked, cmd == WALK_TREE_RESTORE ? TRUE : FALSE);
  141. tvi.iImage = (tvi.iImage == IDCHECKED) || (tvi.iImage == IDUNCHECKED) ?
  142. (bChecked ? IDCHECKED : IDUNCHECKED) :
  143. (bChecked ? IDRADIOON : IDRADIOOFF);
  144. tvi.iSelectedImage = tvi.iImage;
  145. TreeView_SetItem(m_hwndTree, &tvi);
  146. }
  147. break;
  148. }
  149. return TRUE; // success?
  150. }
  151. /////////////////////////////////////////////////////////////////////
  152. BOOL IsValidKey(HKEY hkeyRoot, LPCTSTR pszSubKey, LPCTSTR pszValue)
  153. {
  154. TCHAR szPath[MAX_PATH];
  155. DWORD dwType, cbSize = sizeof(szPath);
  156. if (ERROR_SUCCESS == SHGetValue(hkeyRoot, pszSubKey, pszValue, &dwType, szPath, &cbSize))
  157. {
  158. // Zero in the DWORD case or NULL in the string case
  159. // indicates that this item is not available.
  160. if (dwType == REG_DWORD)
  161. return *((DWORD *)szPath) != 0;
  162. else
  163. return szPath[0] != 0;
  164. }
  165. return FALSE;
  166. }
  167. /////////////////////////////////////////////////////////////////////
  168. HRESULT CRegTreeOptions::WalkTree(WALK_TREE_CMD cmd)
  169. {
  170. HTREEITEM htvi = TreeView_GetRoot( m_hwndTree );
  171. // and walk the list of other roots
  172. while (htvi)
  173. {
  174. // recurse through its children
  175. WalkTreeRecursive(htvi, cmd);
  176. // get the next root
  177. htvi = TreeView_GetNextSibling( m_hwndTree, htvi );
  178. }
  179. return S_OK; // success?
  180. }
  181. #define REGSTR_POLICIES_EXPLORER TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer")
  182. /////////////////////////////////////////////////////////////////////
  183. BOOL CRegTreeOptions::RegIsRestricted(HKEY hsubkey)
  184. {
  185. HKEY hkey;
  186. BOOL fRet = FALSE;
  187. // Does a "Policy" Sub key exist?
  188. if (RegOpenKeyEx(hsubkey, TEXT("Policy"), 0, KEY_READ, &hkey) == ERROR_SUCCESS)
  189. {
  190. // Yes; Enumerate this key. The Values are Policy keys or
  191. // Full reg paths.
  192. DWORD cb;
  193. TCHAR szKeyName[ MAX_KEY_NAME ];
  194. FILETIME ftLastWriteTime;
  195. for (int i=0;
  196. cb = ARRAYSIZE( szKeyName ),
  197. ERROR_SUCCESS == RegEnumKeyEx( hkey, i, szKeyName, &cb, NULL, NULL, NULL, &ftLastWriteTime )
  198. && !fRet; i++)
  199. {
  200. TCHAR szPath[MAXIMUM_SUB_KEY_LENGTH];
  201. DWORD dwType, cbSize = sizeof(szPath);
  202. if (ERROR_SUCCESS == SHGetValue(hkey, szKeyName, TEXT("RegKey"), &dwType, szPath, &cbSize))
  203. {
  204. if (IsValidKey(HKEY_LOCAL_MACHINE, szPath, szKeyName))
  205. {
  206. fRet = TRUE;
  207. break;
  208. }
  209. }
  210. // It's not a full Key, try off of policies
  211. if (IsValidKey(HKEY_LOCAL_MACHINE, REGSTR_POLICIES_EXPLORER, szKeyName) ||
  212. IsValidKey(HKEY_CURRENT_USER, REGSTR_POLICIES_EXPLORER, szKeyName))
  213. {
  214. fRet = TRUE;
  215. break;
  216. }
  217. }
  218. RegCloseKey(hkey);
  219. }
  220. return fRet;
  221. }
  222. /////////////////////////////////////////////////////////////////////
  223. DWORD RegTreeType( LPCTSTR pszType )
  224. {
  225. for (int i = 0; i < ARRAYSIZE(c_aTreeTypes); i++)
  226. {
  227. if (!lstrcmpi(pszType, c_aTreeTypes[i].name))
  228. return c_aTreeTypes[i].type;
  229. }
  230. return TREE_UNKNOWN;
  231. }
  232. /////////////////////////////////////////////////////////////////////
  233. int CRegTreeOptions::DefaultIconImage(HKEY hkey, int iImage)
  234. {
  235. TCHAR szIcon [ MAX_PATH + 10 ]; // 10 = ",XXXX" plus some more
  236. DWORD cb = sizeof(szIcon);
  237. if (ERROR_SUCCESS ==
  238. SHQueryValueEx(hkey, c_szDefaultBitmap, NULL, NULL, szIcon, &cb))
  239. {
  240. int image;
  241. LPTSTR psz = StrRChr( szIcon, szIcon + lstrlen(szIcon), TEXT(',') );
  242. HICON hicon = NULL;
  243. ASSERT( psz ); // shouldn't be zero
  244. if ( !psz )
  245. return iImage;
  246. *psz++ = 0; // terminate and move over
  247. image = StrToInt( psz ); // get ID
  248. if (!*szIcon)
  249. {
  250. hicon = (HICON)LoadIcon(g_hInstance, (LPCTSTR)(INT_PTR)image);
  251. }
  252. else
  253. {
  254. // get the bitmap from the library
  255. ExtractIconEx(szIcon, (UINT)(-1*image), NULL, &hicon, 1 );
  256. if (!hicon)
  257. ExtractIconEx(szIcon, (UINT)(-1*image), &hicon, NULL, 1 );
  258. }
  259. if (hicon)
  260. {
  261. iImage = ImageList_AddIcon( m_hIml, (HICON)hicon);
  262. // NOTE: The docs say you don't need to do a delete object on icons loaded by LoadIcon, but
  263. // you do for CreateIcon. It doesn't say what to do for ExtractIcon, so we'll just call it anyway.
  264. DestroyIcon( hicon );
  265. }
  266. }
  267. return iImage;
  268. }
  269. /////////////////////////////////////////////////////////////////////
  270. DWORD CRegTreeOptions::RegGetSetSetting(HKEY hKey, DWORD *pType, LPBYTE pData, DWORD *pcbData, REG_CMD cmd)
  271. {
  272. DWORD dwRet = ERROR_SUCCESS;
  273. __try
  274. {
  275. if (cmd == REG_GETDEFAULT)
  276. dwRet = SHQueryValueEx(hKey, c_szDefaultValue, NULL, pType, pData, pcbData);
  277. else
  278. {
  279. // support for masks
  280. DWORD dwMask = 0xFFFFFFFF; // Default value
  281. DWORD cb = sizeof(dwMask);
  282. BOOL fMask = (SHQueryValueEx(hKey, c_szMask, NULL, NULL, &dwMask, &cb) == ERROR_SUCCESS);
  283. // support for structures
  284. DWORD dwOffset = 0; // Default value
  285. cb = sizeof(dwOffset);
  286. //TODO: uncomment BOOL fOffset = (SHQueryValueEx(hKey, c_szOffset, NULL, NULL, &dwOffset, &cb) == ERROR_SUCCESS);
  287. HKEY hkRoot = HKEY_CURRENT_USER; // Preinitialize to keep Win64 happy
  288. cb = sizeof(DWORD); // DWORD, not sizeof(HKEY) or Win64 will get mad
  289. DWORD dwError = SHQueryValueEx(hKey, c_szHKeyRoot, NULL, NULL, &hkRoot, &cb);
  290. hkRoot = (HKEY) LongToHandle(HandleToLong(hkRoot));
  291. if (dwError != ERROR_SUCCESS)
  292. {
  293. // use default
  294. hkRoot = HKEY_CURRENT_USER;
  295. }
  296. dwError = SHQueryValueEx(hKey, c_szDefaultValue, NULL, pType, pData, pcbData);
  297. TCHAR szName[MAX_PATH];
  298. cb = sizeof(szName);
  299. dwError = SHQueryValueEx(hKey, c_szValueName, NULL, NULL, szName, &cb);
  300. if (dwError == ERROR_SUCCESS)
  301. {
  302. // find the matching ACTION_SETTING for this value name
  303. ACTION_SETTING asKey;
  304. StrCpy(asKey.szName, szName);
  305. ACTION_SETTING *pas = (ACTION_SETTING*)bsearch(&asKey, &m_as, m_nASCount, sizeof(m_as[0]),
  306. CompareActionSettingStrings);
  307. switch (cmd)
  308. {
  309. case REG_GET:
  310. // grab the value that we have
  311. /* if (fOffset)
  312. {
  313. // TODO: handle this someday
  314. if (dwOffset < cbData / sizeof(DWORD))
  315. *((DWORD *)pData) = *(pdwData + dwOffset);
  316. else
  317. *((DWORD *)pData) = 0; // Invalid offset, return something vague
  318. *pcbData = sizeof(DWORD);
  319. }
  320. else
  321. */
  322. if (NULL != pas)
  323. {
  324. *((DWORD *)pData) = pas->dwValue;
  325. *pcbData = sizeof(pas->dwValue);
  326. if (fMask)
  327. *((DWORD *)pData) &= dwMask;
  328. }
  329. break;
  330. }
  331. }
  332. if ((cmd == REG_GET) && (dwError != ERROR_SUCCESS))
  333. {
  334. // get the default setting
  335. dwError = SHQueryValueEx(hKey, c_szDefaultValue, NULL, pType, pData, pcbData);
  336. }
  337. return dwError;
  338. }
  339. }
  340. __except(TRUE)
  341. {
  342. }
  343. return dwRet;
  344. }
  345. /////////////////////////////////////////////////////////////////////
  346. DWORD CRegTreeOptions::GetCheckStatus(HKEY hkey, BOOL *pbChecked, BOOL bUseDefault)
  347. {
  348. DWORD dwError, cbData, dwType;
  349. BYTE rgData[32];
  350. DWORD cbDataCHK, dwTypeCHK;
  351. BYTE rgDataCHK[32];
  352. // first, get the setting from the specified location.
  353. cbData = sizeof(rgData);
  354. dwError = RegGetSetSetting(hkey, &dwType, rgData, &cbData, bUseDefault ? REG_GETDEFAULT : REG_GET);
  355. if (dwError == ERROR_SUCCESS)
  356. {
  357. // second, get the value for the "checked" state and compare.
  358. cbDataCHK = sizeof(rgDataCHK);
  359. dwError = SHQueryValueEx(hkey, c_szCheckedValue, NULL, &dwTypeCHK, rgDataCHK, &cbDataCHK);
  360. if (dwError != ERROR_SUCCESS)
  361. {
  362. // ok, we couldn't find the "checked" value, is it because
  363. // it's platform dependent?
  364. cbDataCHK = sizeof(rgDataCHK);
  365. dwError = SHQueryValueEx(hkey,
  366. g_fRunningOnNT ? c_szCheckedValueNT : c_szCheckedValueW95,
  367. NULL, &dwTypeCHK, rgDataCHK, &cbDataCHK);
  368. }
  369. if (dwError == ERROR_SUCCESS)
  370. {
  371. // make sure two value types match.
  372. if ((dwType != dwTypeCHK) &&
  373. (((dwType == REG_BINARY) && (dwTypeCHK == REG_DWORD) && (cbData != 4))
  374. || ((dwType == REG_DWORD) && (dwTypeCHK == REG_BINARY) && (cbDataCHK != 4))))
  375. return ERROR_BAD_FORMAT;
  376. switch (dwType) {
  377. case REG_DWORD:
  378. *pbChecked = (*((DWORD*)rgData) == *((DWORD*)rgDataCHK));
  379. break;
  380. case REG_SZ:
  381. if (cbData == cbDataCHK)
  382. *pbChecked = !lstrcmp((LPTSTR)rgData, (LPTSTR)rgDataCHK);
  383. else
  384. *pbChecked = FALSE;
  385. break;
  386. case REG_BINARY:
  387. if (cbData == cbDataCHK)
  388. *pbChecked = !memcmp(rgData, rgDataCHK, cbData);
  389. else
  390. *pbChecked = FALSE;
  391. break;
  392. default:
  393. return ERROR_BAD_FORMAT;
  394. }
  395. }
  396. }
  397. return dwError;
  398. }
  399. BOOL AppendStatus(LPTSTR pszText,UINT cbText, BOOL fOn)
  400. {
  401. LPTSTR pszTemp;
  402. UINT cbStrLen , cbStatusLen;
  403. //if there's no string specified then return
  404. if (!pszText)
  405. return FALSE;
  406. //Calculate the string lengths
  407. cbStrLen = lstrlen(pszText);
  408. cbStatusLen = fOn ? lstrlen(TEXT("-ON")) : lstrlen(TEXT("-OFF"));
  409. //Remove the old status appended
  410. pszTemp = StrRStrI(pszText,pszText + cbStrLen, TEXT("-ON"));
  411. if(pszTemp)
  412. {
  413. *pszTemp = (TCHAR)0;
  414. cbStrLen = lstrlen(pszText);
  415. }
  416. pszTemp = StrRStrI(pszText,pszText + cbStrLen, TEXT("-OFF"));
  417. if(pszTemp)
  418. {
  419. *pszTemp = (TCHAR)0;
  420. cbStrLen = lstrlen(pszText);
  421. }
  422. //check if we append status text, we'll explode or not
  423. if (cbStrLen + cbStatusLen > cbText)
  424. {
  425. //We'll explode
  426. return FALSE;
  427. }
  428. if (fOn)
  429. {
  430. StrCat(pszText, TEXT("-ON"));
  431. }
  432. else
  433. {
  434. StrCat(pszText, TEXT("-OFF"));
  435. }
  436. return TRUE;
  437. }
  438. HTREEITEM Tree_AddItem(HTREEITEM hParent, LPTSTR pszText, HTREEITEM hInsAfter,
  439. int iImage, HWND hwndTree, HKEY hkey, BOOL *pbExisted)
  440. {
  441. HTREEITEM hItem;
  442. TV_ITEM tvI;
  443. TV_INSERTSTRUCT tvIns;
  444. TCHAR szText[MAX_URL_STRING];
  445. ASSERT(pszText != NULL);
  446. StrCpyN(szText, pszText, ARRAYSIZE(szText));
  447. // NOTE:
  448. // This code segment is disabled because we only enum explorer
  449. // tree in HKCU, so there won't be any duplicates.
  450. // Re-able this code if we start to also enum HKLM that could potentially
  451. // result in duplicates.
  452. // We only want to add an item if it is not already there.
  453. // We do this to handle reading out of HKCU and HKLM.
  454. //
  455. TCHAR szKeyName[ MAX_KEY_NAME ];
  456. tvI.mask = TVIF_HANDLE | TVIF_TEXT;
  457. tvI.pszText = szKeyName;
  458. tvI.cchTextMax = ARRAYSIZE(szKeyName);
  459. for (hItem = TreeView_GetChild(hwndTree, hParent) ;
  460. hItem != NULL ;
  461. hItem = TreeView_GetNextSibling(hwndTree, hItem)
  462. )
  463. {
  464. tvI.hItem = hItem;
  465. if (TreeView_GetItem(hwndTree, &tvI))
  466. {
  467. if (!StrCmp(tvI.pszText, szText))
  468. {
  469. // We found a match!
  470. //
  471. *pbExisted = TRUE;
  472. return hItem;
  473. }
  474. }
  475. }
  476. // Create the item
  477. tvI.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  478. tvI.iImage = iImage;
  479. tvI.iSelectedImage = iImage;
  480. tvI.pszText = szText;
  481. tvI.cchTextMax = lstrlen(szText);
  482. // lParam is the HKEY for this item:
  483. tvI.lParam = (LPARAM)hkey;
  484. // Create insert item
  485. tvIns.item = tvI;
  486. tvIns.hInsertAfter = hInsAfter;
  487. tvIns.hParent = hParent;
  488. // Insert the item into the tree.
  489. hItem = (HTREEITEM) SendMessage(hwndTree, TVM_INSERTITEM, 0,
  490. (LPARAM)(LPTV_INSERTSTRUCT)&tvIns);
  491. *pbExisted = FALSE;
  492. return (hItem);
  493. }
  494. /////////////////////////////////////////////////////////////////////
  495. BOOL CRegTreeOptions::RegEnumTree(HKEY hkeyRoot, LPCSTR pszRoot, HTREEITEM htviparent, HTREEITEM htvins)
  496. {
  497. HKEY hkey, hsubkey;
  498. TCHAR szKeyName[ MAX_KEY_NAME ];
  499. FILETIME ftLastWriteTime;
  500. if (RegOpenKeyExA(hkeyRoot, pszRoot, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
  501. {
  502. int i;
  503. DWORD cb;
  504. BOOL bScreenReaderEnabled = IsScreenReaderEnabled();
  505. // we must search all the sub-keys
  506. for (i=0; // always start with 0
  507. cb=ARRAYSIZE( szKeyName ), // string size
  508. ERROR_SUCCESS ==
  509. RegEnumKeyEx( hkey, i, szKeyName, &cb, NULL, NULL, NULL, &ftLastWriteTime );
  510. i++) // get next entry
  511. {
  512. // get more info on the entry
  513. if ( ERROR_SUCCESS ==
  514. RegOpenKeyEx( hkey, szKeyName, 0, KEY_READ, &hsubkey ) )
  515. {
  516. TCHAR szTemp[MAX_PATH];
  517. HKEY hkeySave = NULL;
  518. if (!RegIsRestricted(hsubkey))
  519. {
  520. // Get the type of items under this root
  521. cb = ARRAYSIZE( szTemp );
  522. if ( ERROR_SUCCESS ==
  523. SHQueryValueEx( hsubkey, c_szType, NULL, NULL, szTemp, &cb ))
  524. {
  525. HTREEITEM htviroot;
  526. int iImage = -1;
  527. BOOL bChecked = FALSE;
  528. DWORD dwError = ERROR_SUCCESS;
  529. // get the type of node
  530. DWORD dwTreeType = RegTreeType( szTemp );
  531. // get some more info about the this item
  532. switch (dwTreeType)
  533. {
  534. case TREE_GROUP:
  535. iImage = DefaultIconImage(hsubkey, IDUNKNOWN);
  536. hkeySave = hsubkey;
  537. break;
  538. case TREE_CHECKBOX:
  539. dwError = GetCheckStatus(hsubkey, &bChecked, FALSE);
  540. if (dwError == ERROR_SUCCESS)
  541. {
  542. iImage = bChecked ? IDCHECKED : IDUNCHECKED;
  543. hkeySave = hsubkey;
  544. }
  545. break;
  546. case TREE_RADIO:
  547. dwError = GetCheckStatus(hsubkey, &bChecked, FALSE);
  548. if (dwError == ERROR_SUCCESS)
  549. {
  550. iImage = bChecked ? IDRADIOON : IDRADIOOFF;
  551. hkeySave = hsubkey;
  552. }
  553. break;
  554. default:
  555. dwError = ERROR_INVALID_PARAMETER;
  556. }
  557. if (dwError == ERROR_SUCCESS)
  558. {
  559. BOOL bItemExisted = FALSE;
  560. int cch;
  561. LPTSTR pszText;
  562. HRESULT hr = S_OK;
  563. cch = ARRAYSIZE(szTemp);
  564. // try to get the plugUI enabled text
  565. // otherwise we want the old data from a
  566. // different value
  567. hr = SHLoadRegUIString(hsubkey, c_szPlugUIText, szTemp, cch);
  568. if (SUCCEEDED(hr) && szTemp[0] != TEXT('@'))
  569. {
  570. pszText = szTemp;
  571. }
  572. else
  573. {
  574. // try to get the old non-plugUI enabled text
  575. hr = SHLoadRegUIString(hsubkey, c_szText, szTemp, cch);
  576. if (SUCCEEDED(hr))
  577. {
  578. pszText = szTemp;
  579. }
  580. else
  581. {
  582. // if all else fails, the key name itself
  583. // is a little more useful than garbage
  584. pszText = szKeyName;
  585. cch = ARRAYSIZE(szKeyName);
  586. }
  587. }
  588. //See if we need to add status text
  589. if (bScreenReaderEnabled && (dwTreeType != TREE_GROUP))
  590. {
  591. AppendStatus(pszText, cch, bChecked);
  592. }
  593. // add root node
  594. htviroot = Tree_AddItem(htviparent, pszText, htvins, iImage, m_hwndTree, hkeySave, &bItemExisted);
  595. if (bItemExisted)
  596. hkeySave = NULL;
  597. if (dwTreeType == TREE_GROUP)
  598. {
  599. CHAR szKeyNameTemp[MAX_KEY_NAME];
  600. SHTCharToAnsi(szKeyName, szKeyNameTemp, ARRAYSIZE(szKeyNameTemp));
  601. RegEnumTree(hkey, szKeyNameTemp, htviroot, TVI_FIRST);
  602. TreeView_Expand(m_hwndTree, htviroot, TVE_EXPAND);
  603. }
  604. } // if (dwError == ERROR_SUCCESS
  605. }
  606. } // if (!RegIsRestricted(hsubkey))
  607. if (hkeySave != hsubkey)
  608. RegCloseKey(hsubkey);
  609. }
  610. }
  611. // Sort all keys under htviparent
  612. SendMessage(m_hwndTree, TVM_SORTCHILDREN, 0, (LPARAM)htviparent);
  613. RegCloseKey( hkey );
  614. return TRUE;
  615. }
  616. return FALSE;
  617. }
  618. ///////////////////////////////////////////////////////////////////////////////
  619. HRESULT CRegTreeOptions::InitTree(HWND hwndTree, HKEY hkeyRoot, LPCSTR pszRegKey,
  620. LPSECURITYPAGE pSec)
  621. {
  622. HRESULT hr = S_OK;
  623. __try
  624. {
  625. g_fRunningOnNT = IsOS(OS_NT);
  626. if (g_fRunningOnNT)
  627. {
  628. g_bRunOnNT5 = IsOS(OS_NT5);
  629. g_fRunOnWhistler = IsOS(OS_WHISTLERORGREATER);
  630. }
  631. else
  632. g_bRunOnMemphis = IsOS(OS_WIN98);
  633. g_fRunOnFE = GetSystemMetrics(SM_DBCSENABLED);
  634. m_hwndTree = hwndTree;
  635. m_hIml = ImageList_Create( BITMAP_WIDTH, BITMAP_HEIGHT,
  636. ILC_COLOR | ILC_MASK, NUM_BITMAPS, 4 );
  637. // Initialize the tree view window.
  638. LONG_PTR flags = GetWindowLongPtr(hwndTree, GWL_STYLE);
  639. SetWindowLongPtr(hwndTree, GWL_STYLE, flags & ~TVS_CHECKBOXES);
  640. HBITMAP hBmp = CreateMappedBitmap(g_hInstance, IDB_BUTTONS, 0, NULL, 0);
  641. ImageList_AddMasked( m_hIml, hBmp, CLR_DEFAULT);
  642. DeleteObject( hBmp );
  643. // Associate the image list with the tree.
  644. HIMAGELIST himl = TreeView_SetImageList( hwndTree, m_hIml, TVSIL_NORMAL );
  645. if (himl)
  646. ImageList_Destroy(himl);
  647. // Let accessibility know about our state images
  648. // TODO: what do we do with this?
  649. // SetProp(hwndTree, TEXT("MSAAStateImageMapCount"), LongToPtr(ARRAYSIZE(c_rgimeTree)));
  650. // SetProp(hwndTree, TEXT("MSAAStateImageMapAddr"), (HANDLE)c_rgimeTree);
  651. //
  652. // RSoP portion
  653. //
  654. // get the RSOP_IEProgramSettings object and its properties
  655. ComPtr<IWbemServices> pWbemServices = pSec->pDRD->GetWbemServices();
  656. _bstr_t bstrObjPath = pSec->pszs->wszObjPath;
  657. ComPtr<IWbemClassObject> pSZObj = NULL;
  658. HRESULT hr = pWbemServices->GetObject(bstrObjPath, 0L, NULL, (IWbemClassObject**)&pSZObj, NULL);
  659. if (SUCCEEDED(hr))
  660. {
  661. // actionValues field
  662. _variant_t vtValue;
  663. hr = pSZObj->Get(L"actionValues", 0, &vtValue, NULL, NULL);
  664. if (SUCCEEDED(hr) && !IsVariantNull(vtValue))
  665. {
  666. SAFEARRAY *psa = vtValue.parray;
  667. LONG lLBound, lUBound;
  668. hr = SafeArrayGetLBound(psa, 1, &lLBound);
  669. hr = SafeArrayGetUBound(psa, 1, &lUBound);
  670. if (SUCCEEDED(hr))
  671. {
  672. LONG cElements = lUBound - lLBound + 1;
  673. BSTR HUGEP *pbstr = NULL;
  674. hr = SafeArrayAccessData(psa, (void HUGEP**)&pbstr);
  675. if (SUCCEEDED(hr))
  676. {
  677. long nASCount = 0;
  678. for (long nVal = 0; nVal < cElements; nVal++)
  679. {
  680. LPCTSTR szAction = (LPCTSTR)pbstr[nVal];
  681. LPTSTR szColon = StrChr(szAction, _T(':'));
  682. if (NULL != szColon)
  683. {
  684. StrCpyN(m_as[nASCount].szName, szAction, (int)((szColon - szAction) + 1));
  685. szColon++;
  686. m_as[nASCount].dwValue = StrToInt(szColon);
  687. nASCount++;
  688. }
  689. }
  690. m_nASCount = nASCount;
  691. // now sort the list by precedence
  692. if (m_nASCount > 0)
  693. qsort(&m_as, m_nASCount, sizeof(m_as[0]), CompareActionSettingStrings);
  694. }
  695. SafeArrayUnaccessData(psa);
  696. }
  697. }
  698. }
  699. RegEnumTree(hkeyRoot, pszRegKey, NULL, TVI_ROOT);
  700. }
  701. __except(TRUE)
  702. {
  703. }
  704. return hr;
  705. }
  706. /////////////////////////////////////////////////////////////////////
  707. void ShowCustom(LPCUSTOMSETTINGSINFO pcsi, HTREEITEM hti)
  708. {
  709. TV_ITEM tvi;
  710. tvi.hItem = hti;
  711. tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE;
  712. TreeView_GetItem( pcsi->hwndTree, &tvi );
  713. // If it's not selected don't bother.
  714. if (tvi.iImage != IDRADIOON)
  715. return;
  716. TCHAR szValName[64];
  717. DWORD cb = sizeof(szValName);
  718. DWORD dwChecked;
  719. if (RegQueryValueEx((HKEY)tvi.lParam,
  720. TEXT("ValueName"),
  721. NULL,
  722. NULL,
  723. (LPBYTE)szValName,
  724. &cb) == ERROR_SUCCESS)
  725. {
  726. if (!(StrCmp(szValName, TEXT("1C00"))))
  727. {
  728. cb = sizeof(dwChecked);
  729. if (RegQueryValueEx((HKEY)tvi.lParam,
  730. TEXT("CheckedValue"),
  731. NULL,
  732. NULL,
  733. (LPBYTE)&dwChecked,
  734. &cb) == ERROR_SUCCESS)
  735. {
  736. #ifndef UNIX
  737. HWND hCtl = GetDlgItem(pcsi->hDlg, IDC_JAVACUSTOM);
  738. ShowWindow(hCtl,
  739. (dwChecked == URLPOLICY_JAVA_CUSTOM) && (tvi.iImage == IDRADIOON) ? SW_SHOWNA : SW_HIDE);
  740. EnableWindow(hCtl, dwChecked==URLPOLICY_JAVA_CUSTOM ? TRUE : FALSE);
  741. pcsi->dwJavaPolicy = dwChecked;
  742. #endif
  743. }
  744. }
  745. }
  746. }
  747. /////////////////////////////////////////////////////////////////////
  748. void _FindCustomRecursive(LPCUSTOMSETTINGSINFO pcsi, HTREEITEM htvi)
  749. {
  750. HTREEITEM hctvi; // child
  751. // step through the children
  752. hctvi = TreeView_GetChild( pcsi->hwndTree, htvi );
  753. while ( hctvi )
  754. {
  755. _FindCustomRecursive(pcsi,hctvi);
  756. hctvi = TreeView_GetNextSibling( pcsi->hwndTree, hctvi );
  757. }
  758. //TODO: Display custom java settings button later
  759. // ShowCustom(pcsi, htvi);
  760. }
  761. /////////////////////////////////////////////////////////////////////
  762. void _FindCustom(LPCUSTOMSETTINGSINFO pcsi)
  763. {
  764. HTREEITEM hti = TreeView_GetRoot( pcsi->hwndTree );
  765. // and walk the list of other roots
  766. while (hti)
  767. {
  768. // recurse through its children
  769. _FindCustomRecursive(pcsi, hti);
  770. // get the next root
  771. hti = TreeView_GetNextSibling(pcsi->hwndTree, hti );
  772. }
  773. }
  774. /////////////////////////////////////////////////////////////////////
  775. BOOL SecurityCustomSettingsInitDialog(HWND hDlg, LPARAM lParam)
  776. {
  777. LPCUSTOMSETTINGSINFO pcsi = (LPCUSTOMSETTINGSINFO)LocalAlloc(LPTR, sizeof(*pcsi));
  778. HRESULT hr = S_OK;
  779. if (!pcsi)
  780. {
  781. EndDialog(hDlg, IDCANCEL);
  782. return FALSE;
  783. }
  784. // tell dialog where to get info
  785. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pcsi);
  786. // save the handle to the page
  787. pcsi->hDlg = hDlg;
  788. pcsi->pSec = (LPSECURITYPAGE)lParam;
  789. // save dialog handle
  790. pcsi->hwndTree = GetDlgItem(pcsi->hDlg, IDC_TREE_SECURITY_SETTINGS);
  791. pcsi->pTO = new CRegTreeOptions;
  792. DWORD cb = sizeof(pcsi->fUseHKLM);
  793. SHGetValue(HKEY_LOCAL_MACHINE,
  794. REGSTR_PATH_SECURITY_LOCKOUT,
  795. REGSTR_VAL_HKLM_ONLY,
  796. NULL,
  797. &(pcsi->fUseHKLM),
  798. &cb);
  799. // if this fails, we'll just use the default of fUseHKLM == 0
  800. if (SUCCEEDED(hr))
  801. {
  802. pcsi->pTO->InitTree(pcsi->hwndTree, HKEY_LOCAL_MACHINE, pcsi->fUseHKLM ?
  803. "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\SOIEAK" :
  804. "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\SO",
  805. pcsi->pSec);
  806. }
  807. // find the first root and make sure that it is visible
  808. TreeView_EnsureVisible( pcsi->hwndTree, TreeView_GetRoot( pcsi->hwndTree ) );
  809. pcsi->hwndCombo = GetDlgItem(hDlg, IDC_COMBO_RESETLEVEL);
  810. SendMessage(pcsi->hwndCombo, CB_INSERTSTRING, (WPARAM)0, (LPARAM)LEVEL_NAME[3]);
  811. SendMessage(pcsi->hwndCombo, CB_INSERTSTRING, (WPARAM)0, (LPARAM)LEVEL_NAME[2]);
  812. SendMessage(pcsi->hwndCombo, CB_INSERTSTRING, (WPARAM)0, (LPARAM)LEVEL_NAME[1]);
  813. SendMessage(pcsi->hwndCombo, CB_INSERTSTRING, (WPARAM)0, (LPARAM)LEVEL_NAME[0]);
  814. switch (pcsi->pSec->pszs->dwRecSecLevel)
  815. {
  816. case URLTEMPLATE_LOW:
  817. pcsi->iLevelSel = 3;
  818. break;
  819. case URLTEMPLATE_MEDLOW:
  820. pcsi->iLevelSel = 2;
  821. break;
  822. case URLTEMPLATE_MEDIUM:
  823. pcsi->iLevelSel = 1;
  824. break;
  825. case URLTEMPLATE_HIGH:
  826. pcsi->iLevelSel = 0;
  827. break;
  828. default:
  829. pcsi->iLevelSel = 0;
  830. break;
  831. }
  832. _FindCustom(pcsi);
  833. SendMessage(pcsi->hwndCombo, CB_SETCURSEL, (WPARAM)pcsi->iLevelSel, (LPARAM)0);
  834. EnableDlgItem2(hDlg, IDC_COMBO_RESETLEVEL, FALSE);
  835. EnableDlgItem2(hDlg, IDC_BUTTON_APPLY, FALSE);
  836. pcsi->fChanged = FALSE;
  837. return TRUE;
  838. }
  839. /////////////////////////////////////////////////////////////////////
  840. int RegWriteWarning(HWND hParent)
  841. {
  842. // load "Warning!"
  843. TCHAR szWarning[64];
  844. LoadString(g_hInstance, IDS_WARNING, szWarning, ARRAYSIZE(szWarning));
  845. // Load "You are about to write..."
  846. TCHAR szWriteWarning[128];
  847. LoadString(g_hInstance, IDS_WRITE_WARNING, szWriteWarning, ARRAYSIZE(szWriteWarning));
  848. return MessageBox(hParent, szWriteWarning, szWarning, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
  849. }
  850. /////////////////////////////////////////////////////////////////////
  851. INT_PTR CALLBACK SecurityCustomSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  852. {
  853. LPCUSTOMSETTINGSINFO pcsi;
  854. if (uMsg == WM_INITDIALOG)
  855. {
  856. BOOL fRet = SecurityCustomSettingsInitDialog(hDlg, lParam);
  857. // EnableDlgItem2(hDlg, IDC_TREE_SECURITY_SETTINGS, FALSE);
  858. return fRet;
  859. }
  860. else
  861. pcsi = (LPCUSTOMSETTINGSINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  862. if (!pcsi)
  863. return FALSE;
  864. switch (uMsg) {
  865. case WM_NOTIFY:
  866. {
  867. LPNMHDR psn = (LPNMHDR)lParam;
  868. switch( psn->code )
  869. {
  870. case TVN_KEYDOWN:
  871. break;
  872. case NM_CLICK:
  873. case NM_DBLCLK:
  874. break;
  875. }
  876. }
  877. break;
  878. case WM_COMMAND:
  879. switch (LOWORD(wParam))
  880. {
  881. case IDOK:
  882. EndDialog(hDlg, IDOK);
  883. break;
  884. case IDCANCEL:
  885. EndDialog(hDlg, IDCANCEL);
  886. break;
  887. case IDC_COMBO_RESETLEVEL:
  888. switch (HIWORD(wParam))
  889. {
  890. case CBN_SELCHANGE:
  891. {
  892. // Sundown: coercion to integer since cursor selection is 32b
  893. int iNewSelection = (int) SendMessage(pcsi->hwndCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
  894. if (iNewSelection != pcsi->iLevelSel)
  895. {
  896. pcsi->iLevelSel = iNewSelection;
  897. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_APPLY),TRUE);
  898. }
  899. break;
  900. }
  901. }
  902. break;
  903. case IDC_JAVACUSTOM:
  904. //TODO: uncomment ShowJavaZonePermissionsDialog(hDlg, pcsi);
  905. break;
  906. case IDC_BUTTON_APPLY:
  907. break;
  908. default:
  909. return FALSE;
  910. }
  911. return TRUE;
  912. break;
  913. case WM_HELP: // F1
  914. {
  915. //TODO: implement
  916. /* LPHELPINFO lphelpinfo;
  917. lphelpinfo = (LPHELPINFO)lParam;
  918. TV_HITTESTINFO ht;
  919. HTREEITEM hItem;
  920. // If this help is invoked through the F1 key.
  921. if (GetAsyncKeyState(VK_F1) < 0)
  922. {
  923. // Yes we need to give help for the currently selected item.
  924. hItem = TreeView_GetSelection(pcsi->hwndTree);
  925. }
  926. else
  927. {
  928. // Else we need to give help for the item at current cursor position
  929. ht.pt =((LPHELPINFO)lParam)->MousePos;
  930. ScreenToClient(pcsi->hwndTree, &ht.pt); // Translate it to our window
  931. hItem = TreeView_HitTest(pcsi->hwndTree, &ht);
  932. }
  933. if (FAILED(pcsi->pTO->ShowHelp(hItem , HELP_WM_HELP)))
  934. {
  935. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  936. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  937. }
  938. */ break;
  939. }
  940. case WM_CONTEXTMENU: // right mouse click
  941. {
  942. //TODO: implement
  943. /* TV_HITTESTINFO ht;
  944. GetCursorPos( &ht.pt ); // get where we were hit
  945. ScreenToClient( pcsi->hwndTree, &ht.pt ); // translate it to our window
  946. // retrieve the item hit
  947. if (FAILED(pcsi->pTO->ShowHelp(TreeView_HitTest( pcsi->hwndTree, &ht),HELP_CONTEXTMENU)))
  948. {
  949. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  950. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  951. }
  952. */ break;
  953. }
  954. case WM_DESTROY:
  955. if (pcsi)
  956. {
  957. if (pcsi->pTO)
  958. {
  959. pcsi->pTO->WalkTree( WALK_TREE_DELETE );
  960. delete pcsi->pTO;
  961. pcsi->pTO = NULL;
  962. }
  963. LocalFree(pcsi);
  964. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
  965. }
  966. break;
  967. }
  968. return FALSE;
  969. }