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.

4505 lines
137 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000
  6. //
  7. // File: cpnamespc.cpp
  8. //
  9. // This is a rather large module but it's not all that difficult. The
  10. // primary purpose is to provide the 'data' associated with the new
  11. // 'categorized' Control Panel user interface. Therefore, the visual
  12. // work is done in cpview.cpp and the data is provided by cpnamespc.cpp.
  13. // Through the implementation of ICplNamespace, the 'view' object obtains
  14. // it's display information. All of this 'namespace' information is
  15. // defined and made accessible through this module.
  16. //
  17. // The 'namespace' can be broken down into these concepts:
  18. //
  19. // 1. Links - title, icon & infotip
  20. // 2. Actions
  21. // 3. Restrictions
  22. //
  23. // Each link has a title, icon, infotip and an associated action. The
  24. // action is 'invoked' when the user selects the link in the user interface.
  25. // Actions may optionally be associated with a 'restriction'. If a
  26. // restriction is enforced (usually based on some system state) the
  27. // link associated with the action that is associated with the restriction
  28. // is not made available to the user interface. Using this indirection
  29. // mechanism, any link related to a restricted action is not displayed.
  30. //
  31. // At first glance one might be concerned with the amount of global data
  32. // used (and being initialized). Note however that all of the information
  33. // is defined as constant such that it can be resolved at compile and link
  34. // time. Several goals drove the design of this module:
  35. //
  36. // 1. Easy maintenance of Control Panel content. It must be easy
  37. // to add/remove/modify links in the UI.
  38. //
  39. // 2. Fast initialization. Everything is defined as constant data.
  40. //
  41. // 3. Logical separation of links, actions and restrictions
  42. // to facilitate the one-to-many and many-to-many relationships
  43. // that might occur in the namespace.
  44. //
  45. // Following the namespace initialization code, the remainder of the
  46. // module implements ICplNamespace to make the data available to the view
  47. // in a COM-friendly way.
  48. //
  49. //--------------------------------------------------------------------------
  50. #include "shellprv.h"
  51. #include <cowsite.h>
  52. #include <startids.h>
  53. #include "cpviewp.h"
  54. #include "cpaction.h"
  55. #include "cpguids.h"
  56. #include "cpnamespc.h"
  57. #include "cpuiele.h"
  58. #include "cputil.h"
  59. #include "ids.h"
  60. #include "securent.h"
  61. #include "prop.h"
  62. //
  63. // These icons are currently all the same image.
  64. // Use separate macro names in the code in case the designers
  65. // decide to use different icons for one or more.
  66. //
  67. #define IDI_CPTASK_SEEALSO IDI_CPTASK_ASSISTANCE
  68. #define IDI_CPTASK_TROUBLESHOOTER IDI_CPTASK_ASSISTANCE
  69. #define IDI_CPTASK_HELPANDSUPPORT IDI_CPTASK_ASSISTANCE
  70. #define IDI_CPTASK_LEARNABOUT IDI_CPTASK_ASSISTANCE
  71. namespace CPL {
  72. typedef CDpa<UNALIGNED ITEMIDLIST, CDpaDestroyer_ILFree<UNALIGNED ITEMIDLIST> > CDpaItemIDList;
  73. typedef CDpa<IUICommand, CDpaDestroyer_Release<IUICommand> > CDpaUiCommand;
  74. //
  75. // WebView info type enumeration.
  76. //
  77. enum eCPWVTYPE
  78. {
  79. eCPWVTYPE_CPANEL, // The 'Control Panel' item.
  80. eCPWVTYPE_SEEALSO, // The 'See Also' list.
  81. eCPWVTYPE_TROUBLESHOOT, // The 'Troubleshooters' list.
  82. eCPWVTYPE_LEARNABOUT, // The 'Learn About' list.
  83. eCPWVTYPE_NUMTYPES
  84. };
  85. //
  86. // Define the SCID identifying the control panel category.
  87. //
  88. DEFINE_SCID(SCID_CONTROLPANELCATEGORY, PSGUID_CONTROLPANEL, PID_CONTROLPANEL_CATEGORY);
  89. //-----------------------------------------------------------------------------
  90. // Resource source classes
  91. //
  92. // The purpose of this trivial class is to abstract away the implementation
  93. // of obtaining a resource identifier. The reason for this comes from needing
  94. // different text resources (i.e. infotips) for different retail SKUs.
  95. // For example, on Personal SKU, the Users & Passwords applet provides the
  96. // ability to associate a picture with a user's account. On Server, it
  97. // does not. Therefore, the infotip on Personal can include text about
  98. // the user's picture while on Server it cannot. By introducing this level
  99. // of abstraction, we can provide resource information through a resource
  100. // function that can select the appropriate resource at runtime. Most
  101. // links will still use fixed resources but with this abstraction, the calling
  102. // code is none the wiser.
  103. //-----------------------------------------------------------------------------
  104. //
  105. // Resource source function must return an LPCWSTR for the resource.
  106. //
  107. typedef LPCWSTR (*PFNRESOURCE)(ICplNamespace *pns);
  108. class IResSrc
  109. {
  110. public:
  111. virtual LPCWSTR GetResource(ICplNamespace *pns) const = 0;
  112. };
  113. class CResSrcStatic : public IResSrc
  114. {
  115. public:
  116. CResSrcStatic(LPCWSTR pszResource)
  117. : m_pszResource(pszResource) { }
  118. LPCWSTR GetResource(ICplNamespace *pns) const
  119. { UNREFERENCED_PARAMETER(pns);
  120. TraceMsg(TF_CPANEL, "CResSrc::GetResource - m_pszResource = 0x%08X", m_pszResource);
  121. return m_pszResource; }
  122. private:
  123. const LPCWSTR m_pszResource;
  124. };
  125. class CResSrcFunc : public IResSrc
  126. {
  127. public:
  128. CResSrcFunc(PFNRESOURCE pfnResource)
  129. : m_pfnResource(pfnResource) { }
  130. LPCWSTR GetResource(ICplNamespace *pns) const
  131. { TraceMsg(TF_CPANEL, "CResSrcFunc::GetResource - m_pfnResource = 0x%08X", m_pfnResource);
  132. return (*m_pfnResource)(pns); }
  133. private:
  134. const PFNRESOURCE m_pfnResource;
  135. };
  136. //
  137. // This resource type represents "no resource". It simply
  138. // returns a NULL value when the resource is requested. Clients
  139. // that call this must be ready to handle this NULL pointer
  140. // value. It was originally created to handle the no-tooltip
  141. // behavior of Learn-About links.
  142. //
  143. class CResSrcNone : public IResSrc
  144. {
  145. public:
  146. CResSrcNone(void) { }
  147. LPCWSTR GetResource(ICplNamespace *pns) const
  148. { UNREFERENCED_PARAMETER(pns);
  149. return NULL; }
  150. };
  151. // ----------------------------------------------------------------------------
  152. // Information describing links.
  153. // ----------------------------------------------------------------------------
  154. //
  155. //
  156. // 'Link' descriptor.
  157. //
  158. struct CPLINK_DESC
  159. {
  160. const IResSrc *prsrcIcon; // Icon resource identifier
  161. const IResSrc *prsrcName; // The link's title resource ID.
  162. const IResSrc *prsrcInfotip; // The link's infotip resource ID.
  163. const IAction *pAction; // The link's action when clicked.
  164. };
  165. //
  166. // Set of 'support' links.
  167. //
  168. struct CPLINK_SUPPORT
  169. {
  170. const CPLINK_DESC **ppSeeAlsoLinks; // 'See Also' links for the category.
  171. const CPLINK_DESC **ppTroubleshootLinks; // 'Troubleshoot' links for the category.
  172. const CPLINK_DESC **ppLearnAboutLinks; // 'Learn About' links for the category.
  173. };
  174. //
  175. // 'Category' descriptor. One defined for each category.
  176. //
  177. struct CPCAT_DESC
  178. {
  179. eCPCAT idCategory; // The category's ID.
  180. LPCWSTR pszHelpSelection; // Selection part of HSS help URL.
  181. const CPLINK_DESC *pLink; // The category's display info and action
  182. const CPLINK_DESC **ppTaskLinks; // The category's task list.
  183. CPLINK_SUPPORT slinks; // Support links.
  184. };
  185. // ----------------------------------------------------------------------------
  186. // Restrictions
  187. //
  188. // Restrictions are an important part of the control panel display logic.
  189. // Each link element in the UI can be restricted from view based on one or
  190. // more system conditions at the time of display. To ensure the correct
  191. // logic is used, it is critical to have a method of describing these restrictions
  192. // that is easily readable and verifiable against a specification. Testing
  193. // all of the possible scenarios is a difficult task, therefore the code must
  194. // be written in a manner conducive to finding errors by inspection as well.
  195. // This means, keep it simple. Each link action object can be optionally associated
  196. // with a 'restriction' object. Restriction objects implement CPL::IRestrict.
  197. // The most common restriction object CRestrictFunc simply calls a function
  198. // provided to the object's constructor. The function is called when the
  199. // restriction status (restricted/allowed) is desired. There is also
  200. // class CRestrictApplet for tasks who's presence is directly linked to
  201. // the presence/restriction of a particular CPL applet based on policy alone.
  202. //
  203. // Since there may be many task links on a given Control Panel page that
  204. // means there will be multiple restriction expressions evaluated each
  205. // time the page is displayed. Often the expressions across a set of
  206. // actions are evaluating many of the same terms. Some of these terms require
  207. // registry lookups. To help performance, a simple caching mechanism
  208. // has been introduced into the 'namespace' object. Each restriction function
  209. // is passed a pointer to the current 'namespace' object. As the namespace
  210. // object remains alive the entire time the page is being constructed, it
  211. // is an appropriate place to cache frequently used data. You'll see
  212. // many instances below where the namespace object is queried for restriction
  213. // data. The members of the namespace object associated with this restriction
  214. // data are of type CTriState. This simple class implements the concept of
  215. // an 'uninitialized boolean' value, allowing the code to determine if a given
  216. // boolean member has yet to be initialized with a valid boolean value. If
  217. // the namespace is asked for the value of one of these tri-state booleans
  218. // and that member has not yet been initialized, the namespace calls the
  219. // appropriate system functions and initializes the boolean value. From that
  220. // time forward, the member's value is returned immediately. This ensures that
  221. // for any given restriction term, we do the expensive stuff only once.
  222. // Being an on-demand mechanism, we also gather only the information that is
  223. // needed.
  224. //
  225. // [brianau - 03/18/01]
  226. //
  227. HRESULT Restrict32CtrlPanel(ICplNamespace *pns)
  228. {
  229. HRESULT hr = S_FALSE;
  230. #if defined(WX86) || !defined(_WIN64)
  231. hr = S_OK; // restricted.
  232. #endif
  233. return hr;
  234. }
  235. HRESULT RestrictAlways(ICplNamespace *pns)
  236. {
  237. UNREFERENCED_PARAMETER(pns);
  238. return S_OK; // Always restricted.
  239. }
  240. HRESULT RestrictDisplayCpl(ICplNamespace *pns)
  241. {
  242. HRESULT hr = S_FALSE;
  243. if (!pns->AllowDeskCpl())
  244. {
  245. hr = S_OK;
  246. }
  247. return hr;
  248. }
  249. HRESULT RestrictThemes(ICplNamespace *pns)
  250. {
  251. HRESULT hr = S_FALSE;
  252. if (!pns->AllowDeskCpl() ||
  253. SHRestricted(REST_NOTHEMESTAB) ||
  254. SHRestricted(REST_NODISPLAYAPPEARANCEPAGE))
  255. {
  256. hr = S_OK;
  257. }
  258. return hr;
  259. }
  260. HRESULT RestrictWallpaper(ICplNamespace *pns)
  261. {
  262. HRESULT hr = S_FALSE;
  263. if (!pns->AllowDeskCpl() ||
  264. SHRestricted(REST_NOCHANGINGWALLPAPER) ||
  265. !pns->AllowDeskCplTab_Background())
  266. {
  267. hr = S_OK; // restricted.
  268. }
  269. return hr;
  270. }
  271. HRESULT RestrictScreenSaver(ICplNamespace *pns)
  272. {
  273. HRESULT hr = S_FALSE;
  274. if (!pns->AllowDeskCpl() ||
  275. !pns->AllowDeskCplTab_Screensaver())
  276. {
  277. hr = S_OK; // restricted.
  278. }
  279. return hr;
  280. }
  281. HRESULT RestrictResolution(ICplNamespace *pns)
  282. {
  283. HRESULT hr = S_FALSE;
  284. if (!pns->AllowDeskCpl() ||
  285. !pns->AllowDeskCplTab_Settings())
  286. {
  287. hr = S_OK; // restricted.
  288. }
  289. return hr;
  290. }
  291. HRESULT RestrictAddPrinter(ICplNamespace *pns)
  292. {
  293. UNREFERENCED_PARAMETER(pns);
  294. HRESULT hr = S_FALSE;
  295. if (SHRestricted(REST_NOPRINTERADD) ||
  296. !IsAppletEnabled(NULL, MAKEINTRESOURCEW(IDS_PRNANDFAXFOLDER)))
  297. {
  298. hr = S_OK; // restricted.
  299. }
  300. return hr;
  301. }
  302. HRESULT RestrictRemoteDesktop(ICplNamespace *pns)
  303. {
  304. HRESULT hr = S_FALSE;
  305. if (!pns->IsUserAdmin() || // Admins only.
  306. pns->IsPersonal() || // Not available on personal.
  307. !IsAppletEnabled(L"sysdm.cpl", MAKEINTRESOURCEW(IDS_CPL_SYSTEM))) // Respect sysdm.cpl policy.
  308. {
  309. hr = S_OK; // restricted.
  310. }
  311. return hr;
  312. }
  313. HRESULT RestrictHomeNetwork(ICplNamespace *pns)
  314. {
  315. HRESULT hr = S_FALSE;
  316. if (!pns->IsX86() || // x86 only.
  317. pns->IsOnDomain() || // Not available on domains.
  318. pns->IsServer() || // Not available on server.
  319. !pns->IsUserAdmin() || // Admins only.
  320. !IsAppletEnabled(L"hnetwiz.dll", NULL)) // Respect hnetwiz.dll policy.
  321. {
  322. hr = S_OK; // restricted.
  323. }
  324. return hr;
  325. }
  326. HRESULT RestrictTsNetworking(ICplNamespace *pns)
  327. {
  328. HRESULT hr = S_FALSE;
  329. //
  330. // Available on personal and professional only.
  331. //
  332. if (!(pns->IsPersonal() || pns->IsProfessional()))
  333. {
  334. hr = S_OK; // restricted.
  335. }
  336. return hr;
  337. }
  338. HRESULT RestrictTsInetExplorer(ICplNamespace *pns)
  339. {
  340. HRESULT hr = S_FALSE;
  341. //
  342. // Available on personal and professional only.
  343. //
  344. if (!(pns->IsPersonal() || pns->IsProfessional()))
  345. {
  346. hr = S_OK; // restricted.
  347. }
  348. return hr;
  349. }
  350. HRESULT RestrictTsModem(ICplNamespace *pns)
  351. {
  352. HRESULT hr = S_FALSE;
  353. //
  354. // Available on server only.
  355. //
  356. if (!pns->IsServer())
  357. {
  358. hr = S_OK; // restricted.
  359. }
  360. return hr;
  361. }
  362. HRESULT RestrictTsSharing(ICplNamespace *pns)
  363. {
  364. HRESULT hr = S_FALSE;
  365. //
  366. // Available on server only.
  367. //
  368. if (!pns->IsServer())
  369. {
  370. hr = S_OK; // restricted.
  371. }
  372. return hr;
  373. }
  374. bool ShellKeyExists(SHELLKEY skey, LPCWSTR pszRegName)
  375. {
  376. TCHAR szValue[MAX_PATH];
  377. DWORD cbValue = sizeof(szValue);
  378. return SUCCEEDED(SKGetValue(skey,
  379. pszRegName,
  380. NULL,
  381. NULL,
  382. szValue,
  383. &cbValue));
  384. }
  385. HRESULT RestrictBackupData(ICplNamespace *pns)
  386. {
  387. HRESULT hr = S_FALSE;
  388. //
  389. // Not available if the 'backuppath' shell key is missing.
  390. // This logic is the same as that used by the "Tools" page
  391. // in a volume property sheet.
  392. //
  393. if (!ShellKeyExists(SHELLKEY_HKLM_EXPLORER, TEXT("MyComputer\\BackupPath")))
  394. {
  395. hr = S_OK; // restricted.
  396. }
  397. return hr;
  398. }
  399. HRESULT RestrictDefrag(ICplNamespace *pns)
  400. {
  401. UNREFERENCED_PARAMETER(pns);
  402. HRESULT hr = S_FALSE;
  403. //
  404. // Not available if the 'defragpath' shell key is missing.
  405. // This logic is the same as that used by the "Tools" page
  406. // in a volume property sheet.
  407. //
  408. if (!ShellKeyExists(SHELLKEY_HKLM_EXPLORER, TEXT("MyComputer\\DefragPath")))
  409. {
  410. hr = S_OK; // restricted.
  411. }
  412. return hr;
  413. }
  414. HRESULT RestrictCleanUpDisk(ICplNamespace *pns)
  415. {
  416. HRESULT hr = S_FALSE;
  417. //
  418. // Not available if the 'cleanuppath' shell key is missing.
  419. //
  420. if (!ShellKeyExists(SHELLKEY_HKLM_EXPLORER, TEXT("MyComputer\\CleanupPath")))
  421. {
  422. hr = S_OK; // restricted.
  423. }
  424. return hr;
  425. }
  426. HRESULT RestrictSystemRestore(ICplNamespace *pns)
  427. {
  428. HRESULT hr = S_FALSE;
  429. //
  430. // Available only on x86.
  431. //
  432. if (!pns->IsX86() ||
  433. pns->IsServer() ||
  434. CPL::IsSystemRestoreRestricted())
  435. {
  436. hr = S_OK; // restricted.
  437. }
  438. return hr;
  439. }
  440. HRESULT RestrictPersonalUserManager(ICplNamespace *pns)
  441. {
  442. HRESULT hr = S_FALSE;
  443. if (!pns->AllowUserManager() ||
  444. !pns->UsePersonalUserManager())
  445. {
  446. hr = S_OK;
  447. }
  448. return hr;
  449. }
  450. HRESULT RestrictServerUserManager(ICplNamespace *pns)
  451. {
  452. HRESULT hr = S_FALSE;
  453. if (!pns->AllowUserManager() ||
  454. pns->UsePersonalUserManager())
  455. {
  456. hr = S_OK; // restricted.
  457. }
  458. return hr;
  459. }
  460. HRESULT RestrictFolderOptions(ICplNamespace *pns)
  461. {
  462. UNREFERENCED_PARAMETER(pns);
  463. HRESULT hr = S_FALSE;
  464. if (SHRestricted(REST_NOFOLDEROPTIONS) ||
  465. !IsAppletEnabled(NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_NS_FOLDEROPTIONS)))
  466. {
  467. hr = S_OK;
  468. }
  469. return hr;
  470. }
  471. HRESULT RestrictIfNoAppletsInCplCategory(ICplNamespace *pns, eCPCAT eCategory)
  472. {
  473. int cCplApplets = 0;
  474. HRESULT hr = THR(CplNamespace_GetCategoryAppletCount(pns, eCategory, &cCplApplets));
  475. if (SUCCEEDED(hr))
  476. {
  477. if (0 == cCplApplets)
  478. {
  479. hr = S_OK; // 0 applets means we don't show the link.
  480. }
  481. else
  482. {
  483. hr = S_FALSE;
  484. }
  485. }
  486. return hr;
  487. }
  488. //
  489. // If there are no CPL applets categorized under "Other",
  490. // we hide the "Other CPL Options" link in the UI.
  491. //
  492. HRESULT RestrictOtherCplOptions(ICplNamespace *pns)
  493. {
  494. HRESULT hr = S_FALSE;
  495. if (!CPL::CategoryViewIsActive() ||
  496. S_OK == RestrictIfNoAppletsInCplCategory(pns, eCPCAT_OTHER))
  497. {
  498. hr = S_OK; // restricted.
  499. }
  500. return hr;
  501. }
  502. HRESULT RestrictWindowsUpdate(ICplNamespace *pns)
  503. {
  504. UNREFERENCED_PARAMETER(pns);
  505. HRESULT hr = S_FALSE;
  506. //
  507. // First check the shell's restriction for the "Windows Update"
  508. // item in the start menu. If the admin doesn't want access from
  509. // the start menu, they most likely don't want it from Control Panel either.
  510. //
  511. if (SHRestricted(REST_NOUPDATEWINDOWS))
  512. {
  513. hr = S_OK;
  514. }
  515. if (S_FALSE == hr)
  516. {
  517. //
  518. // Not restricted in start menu.
  519. // How about the global "Disable Windows Update" policy?
  520. //
  521. DWORD dwType;
  522. DWORD dwData;
  523. DWORD cbData = sizeof(dwData);
  524. if (ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER,
  525. L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\WindowsUpdate",
  526. L"DisableWindowsUpdateAccess",
  527. &dwType,
  528. &dwData,
  529. &cbData))
  530. {
  531. if (REG_DWORD == dwType && 1 == dwData)
  532. {
  533. hr = S_OK; // restricted.
  534. }
  535. }
  536. }
  537. return hr;
  538. }
  539. HRESULT RestrictAddLanguage(ICplNamespace *pns)
  540. {
  541. HRESULT hr = S_FALSE;
  542. if (!pns->IsUserAdmin() || !IsAppletEnabled(L"intl.cpl", MAKEINTRESOURCEW(IDS_CPL_REGIONALOPTIONS)))
  543. {
  544. hr = S_OK; // restricted.
  545. }
  546. return hr;
  547. }
  548. //
  549. // Don't show any of the tasks on the "User Accounts" category page if
  550. // our default user accounts manager applet (nusrmgr.cpl) is disabled by
  551. // policy.
  552. //
  553. HRESULT RestrictAccountsCategoryTasks(ICplNamespace *pns)
  554. {
  555. HRESULT hr = S_FALSE;
  556. if (!pns->AllowUserManager())
  557. {
  558. hr = S_OK; // restricted.
  559. }
  560. return hr;
  561. }
  562. HRESULT RestrictAccountsCreate(ICplNamespace *pns)
  563. {
  564. HRESULT hr = S_FALSE;
  565. if (!pns->AllowUserManager() ||
  566. !pns->UsePersonalUserManager() ||
  567. !(pns->IsUserOwner() || pns->IsUserStandard()))
  568. {
  569. hr = S_OK; // restricted.
  570. }
  571. return hr;
  572. }
  573. HRESULT RestrictAccountsCreate2(ICplNamespace *pns)
  574. {
  575. HRESULT hr = S_FALSE;
  576. if (!pns->AllowUserManager() ||
  577. pns->UsePersonalUserManager() ||
  578. !(pns->IsUserOwner() || pns->IsUserStandard()))
  579. {
  580. hr = S_OK; // restricted.
  581. }
  582. return hr;
  583. }
  584. HRESULT RestrictAccountsChange(ICplNamespace *pns)
  585. {
  586. HRESULT hr = S_FALSE;
  587. if (!pns->AllowUserManager() ||
  588. !pns->UsePersonalUserManager() ||
  589. !(pns->IsUserOwner() || pns->IsUserStandard()))
  590. {
  591. hr = S_OK; // restricted.
  592. }
  593. return hr;
  594. }
  595. HRESULT RestrictAccountsPicture(ICplNamespace *pns)
  596. {
  597. HRESULT hr = S_FALSE;
  598. if (!pns->AllowUserManager() || !pns->UsePersonalUserManager())
  599. {
  600. hr = S_OK; // restricted.
  601. }
  602. return hr;
  603. }
  604. HRESULT RestrictLearnAboutAccounts(ICplNamespace *pns)
  605. {
  606. HRESULT hr = S_FALSE;
  607. if (!pns->AllowUserManager() || !pns->UsePersonalUserManager())
  608. {
  609. hr = S_OK;
  610. }
  611. return hr;
  612. }
  613. HRESULT RestrictLearnAboutAccountTypes(ICplNamespace *pns)
  614. {
  615. HRESULT hr = S_FALSE;
  616. if (!pns->AllowUserManager() ||
  617. !pns->UsePersonalUserManager() ||
  618. !IsUserAdmin()) // topic is for non-admins only.
  619. {
  620. hr = S_OK; // restricted.
  621. }
  622. return hr;
  623. }
  624. HRESULT RestrictLearnAboutChangeName(ICplNamespace *pns)
  625. {
  626. HRESULT hr = S_FALSE;
  627. if (!pns->AllowUserManager() ||
  628. !pns->UsePersonalUserManager() ||
  629. !(pns->IsUserLimited() || pns->IsUserGuest()))
  630. {
  631. hr = S_OK; // restricted.
  632. }
  633. return hr;
  634. }
  635. HRESULT RestrictLearnAboutCreateAccount(ICplNamespace *pns)
  636. {
  637. HRESULT hr = S_FALSE;
  638. if (!pns->AllowUserManager() ||
  639. !pns->UsePersonalUserManager() ||
  640. !(pns->IsUserLimited() || pns->IsUserGuest()))
  641. {
  642. hr = S_OK; // restricted.
  643. }
  644. return hr;
  645. }
  646. HRESULT RestrictLearnAboutFUS(ICplNamespace *pns)
  647. {
  648. HRESULT hr = S_FALSE;
  649. if (!pns->AllowUserManager() || !pns->UsePersonalUserManager())
  650. {
  651. hr = S_OK;
  652. }
  653. return hr;
  654. }
  655. HRESULT RestrictHardwareWizard(ICplNamespace *pns)
  656. {
  657. HRESULT hr = S_FALSE;
  658. if (!pns->IsUserAdmin() ||
  659. !IsAppletEnabled(L"hdwwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDHARDWARE)))
  660. {
  661. hr = S_OK; // restricted.
  662. }
  663. return hr;
  664. }
  665. HRESULT RestrictVpnConnections(ICplNamespace *pns)
  666. {
  667. HRESULT hr = S_FALSE;
  668. if (!pns->IsUserAdmin())
  669. {
  670. hr = S_OK; // restricted.
  671. }
  672. return hr;
  673. }
  674. HRESULT RestrictArp(ICplNamespace *pns)
  675. {
  676. UNREFERENCED_PARAMETER(pns);
  677. HRESULT hr = S_FALSE;
  678. //
  679. // Why we don't check SHRestricted(REST_ARP_NOARP)?
  680. //
  681. // 1. We don't hide category links for any reason.
  682. // 2. If that policy is enabled and appwiz.cpl is allowed,
  683. // (remember, those are different policies)
  684. // we'll display the ARP category page and it will still
  685. // show the ARP applet icon. Since there is at least one
  686. // task link or icon, we don't display the "content disabled
  687. // by your admin" barricade. Then the user will click on the
  688. // applet icon and get ARP's "I've been disabled" messagebox.
  689. //
  690. // By not checking this policy, clicking on the category link
  691. // will invoke ARP and ARP will display it's message.
  692. // I think this is a better user experience.
  693. //
  694. if (!IsAppletEnabled(L"appwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDREMOVEPROGRAMS)))
  695. {
  696. hr = S_OK; // restricted.
  697. }
  698. return hr;
  699. }
  700. //
  701. // The ARP category (and it's tasks) are displayed only when there
  702. // are 2+ applets registered for that category (ARP and one or more
  703. // other applets). Unlike RestrictArp() above, we DO want to consider
  704. // SHRestricted(REST_ARP_NOARP). This way if ARP is restricted in
  705. // ANY way, it's related tasks will not appear.
  706. //
  707. HRESULT RestrictArpAddProgram(ICplNamespace *pns)
  708. {
  709. UNREFERENCED_PARAMETER(pns);
  710. HRESULT hr = S_FALSE;
  711. if (SHRestricted(REST_ARP_NOARP) ||
  712. SHRestricted(REST_ARP_NOADDPAGE) ||
  713. !IsAppletEnabled(L"appwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDREMOVEPROGRAMS)))
  714. {
  715. hr = S_OK; // restricted.
  716. }
  717. return hr;
  718. }
  719. HRESULT RestrictArpRemoveProgram(ICplNamespace *pns)
  720. {
  721. UNREFERENCED_PARAMETER(pns);
  722. HRESULT hr = S_FALSE;
  723. if (SHRestricted(REST_ARP_NOARP) ||
  724. SHRestricted(REST_ARP_NOREMOVEPAGE) ||
  725. !IsAppletEnabled(L"appwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDREMOVEPROGRAMS)))
  726. {
  727. hr = S_OK; // restricted.
  728. }
  729. return hr;
  730. }
  731. //-----------------------------------------------------------------------------
  732. // Restriction objects (alphabetical order please)
  733. //-----------------------------------------------------------------------------
  734. //
  735. // To restrict an action, create a restriction object and associate it with the
  736. // action in the Action object declarations below.
  737. //
  738. const CRestrictFunc g_Restrict32CtrlPanel (Restrict32CtrlPanel);
  739. const CRestrictApplet g_RestrictAccessibility (L"access.cpl", MAKEINTRESOURCEW(IDS_CPL_ACCESSIBILITYOPTIONS));
  740. const CRestrictApplet g_RestrictAccessWizard (L"accwiz.exe", NULL);
  741. const CRestrictFunc g_RestrictAccountsCreate (RestrictAccountsCreate);
  742. const CRestrictFunc g_RestrictAccountsCreate2 (RestrictAccountsCreate2);
  743. const CRestrictFunc g_RestrictAccountsChange (RestrictAccountsChange);
  744. const CRestrictFunc g_RestrictAccountsPicture (RestrictAccountsPicture);
  745. const CRestrictFunc g_RestrictAccountsServer (RestrictServerUserManager);
  746. const CRestrictFunc g_RestrictAddLanguage (RestrictAddLanguage);
  747. const CRestrictFunc g_RestrictAddPrinter (RestrictAddPrinter);
  748. const CRestrictApplet g_RestrictAdminTools (NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_NS_ADMIN_TOOLS));
  749. const CRestrictFunc g_RestrictAlways (RestrictAlways);
  750. const CRestrictFunc g_RestrictArp (RestrictArp);
  751. const CRestrictFunc g_RestrictArpAddProgram (RestrictArpAddProgram);
  752. const CRestrictFunc g_RestrictArpRemoveProgram (RestrictArpRemoveProgram);
  753. const CRestrictFunc g_RestrictBackupData (RestrictBackupData);
  754. const CRestrictFunc g_RestrictCleanUpDisk (RestrictCleanUpDisk);
  755. const CRestrictApplet g_RestrictDateTime (L"timedate.cpl", MAKEINTRESOURCEW(IDS_CPL_DATETIME));
  756. const CRestrictFunc g_RestrictDefrag (RestrictDefrag);
  757. const CRestrictFunc g_RestrictDisplayCpl (RestrictDisplayCpl);
  758. const CRestrictFunc g_RestrictFolderOptions (RestrictFolderOptions);
  759. const CRestrictApplet g_RestrictFontsFolder (NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_NS_FONTS));
  760. const CRestrictFunc g_RestrictHomeNetwork (RestrictHomeNetwork);
  761. const CRestrictFunc g_RestrictHardwareWizard (RestrictHardwareWizard);
  762. const CRestrictApplet g_RestrictInternational (L"intl.cpl", MAKEINTRESOURCEW(IDS_CPL_REGIONALOPTIONS));
  763. const CRestrictFunc g_RestrictLearnAboutAccounts (RestrictLearnAboutAccounts);
  764. const CRestrictFunc g_RestrictLearnAboutAccountTypes (RestrictLearnAboutAccountTypes);
  765. const CRestrictFunc g_RestrictLearnAboutChangeName (RestrictLearnAboutChangeName);
  766. const CRestrictFunc g_RestrictLearnAboutCreateAccount(RestrictLearnAboutCreateAccount);
  767. const CRestrictFunc g_RestrictLearnAboutFUS (RestrictLearnAboutFUS);
  768. const CRestrictApplet g_RestrictMousePointers (L"main.cpl", MAKEINTRESOURCEW(IDS_CPL_MOUSE));
  769. const CRestrictApplet g_RestrictNetConnections (L"inetcpl.cpl", MAKEINTRESOURCEW(IDS_CPL_INTERNETOPTIONS));
  770. const CRestrictFunc g_RestrictOtherCplOptions (RestrictOtherCplOptions);
  771. const CRestrictApplet g_RestrictPhoneModemCpl (L"telephon.cpl", MAKEINTRESOURCEW(IDS_CPL_PHONEANDMODEMOPTIONS));
  772. const CRestrictApplet g_RestrictPowerOptions (L"powercfg.cpl", MAKEINTRESOURCEW(IDS_CPL_POWEROPTIONS));
  773. const CRestrictApplet g_RestrictPrinters (NULL, MAKEINTRESOURCEW(IDS_PRNANDFAXFOLDER));
  774. const CRestrictFunc g_RestrictRemoteDesktop (RestrictRemoteDesktop);
  775. const CRestrictFunc g_RestrictResolution (RestrictResolution);
  776. const CRestrictApplet g_RestrictScannersCameras (NULL, MAKEINTRESOURCEW(IDS_CPL_SCANNERSANDCAMERAS));
  777. const CRestrictFunc g_RestrictScreenSaver (RestrictScreenSaver);
  778. const CRestrictApplet g_RestrictScheduledTasks (NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_LNK_SCHEDULED_TASKS));
  779. const CRestrictApplet g_RestrictSounds (L"mmsys.cpl", MAKEINTRESOURCEW(IDS_CPL_SOUNDSANDAUDIO));
  780. const CRestrictApplet g_RestrictSystemCpl (L"sysdm.cpl", MAKEINTRESOURCEW(IDS_CPL_SYSTEM));
  781. const CRestrictFunc g_RestrictSystemRestore (RestrictSystemRestore);
  782. const CRestrictApplet g_RestrictTaskbarProps (NULL, MAKEINTRESOURCEW(IDS_CP_TASKBARANDSTARTMENU));
  783. const CRestrictFunc g_RestrictThemes (RestrictThemes);
  784. const CRestrictFunc g_RestrictTsModem (RestrictTsModem);
  785. const CRestrictFunc g_RestrictTsInetExplorer (RestrictTsInetExplorer);
  786. const CRestrictFunc g_RestrictTsNetworking (RestrictTsNetworking);
  787. const CRestrictFunc g_RestrictTsSharing (RestrictTsSharing);
  788. const CRestrictApplet g_RestrictUserManager (L"nusrmgr.cpl", MAKEINTRESOURCEW(IDS_CPL_USERACCOUNTS));
  789. const CRestrictFunc g_RestrictVpnConnections (RestrictVpnConnections);
  790. const CRestrictFunc g_RestrictWallpaper (RestrictWallpaper);
  791. const CRestrictFunc g_RestrictWindowsUpdate (RestrictWindowsUpdate);
  792. //-----------------------------------------------------------------------------
  793. // Resource functions
  794. //-----------------------------------------------------------------------------
  795. //
  796. // The tooltip for the accounts manager varies based upon the capabilities
  797. // of the application used. On Personal we provide the ability to associate
  798. // a user's picture with their account. The tooltip mentions this. On server
  799. // this capability is not present. Therefore, the tooltip must not mention
  800. // this.
  801. //
  802. LPCWSTR GetCatAccountsInfotip(ICplNamespace *pns)
  803. {
  804. if (pns->AllowUserManager() && pns->UsePersonalUserManager())
  805. {
  806. return MAKEINTRESOURCEW(IDS_CPCAT_ACCOUNTS_INFOTIP);
  807. }
  808. else
  809. {
  810. //
  811. // Personal user manager is restricted. Display the
  812. // infotip without the term "picture".
  813. //
  814. return MAKEINTRESOURCEW(IDS_CPCAT_ACCOUNTS_INFOTIP2);
  815. }
  816. }
  817. LPCWSTR GetAccountsInfotip(ICplNamespace *pns)
  818. {
  819. if (pns->AllowUserManager() && pns->UsePersonalUserManager())
  820. {
  821. return MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_INFOTIP);
  822. }
  823. else
  824. {
  825. //
  826. // Personal user manager is restricted. Display the
  827. // infotip without the term "picture".
  828. //
  829. return MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_INFOTIP2);
  830. }
  831. }
  832. LPCWSTR GetTsNetworkTitle(ICplNamespace *pns)
  833. {
  834. if ((pns->IsPersonal() || pns->IsProfessional()) && !pns->IsOnDomain())
  835. {
  836. return MAKEINTRESOURCE(IDS_CPTASK_TSHOMENETWORKING_TITLE);
  837. }
  838. else
  839. {
  840. return MAKEINTRESOURCE(IDS_CPTASK_TSNETWORK_TITLE);
  841. }
  842. }
  843. //-----------------------------------------------------------------------------
  844. // Action objects (alphabetical order please)
  845. //-----------------------------------------------------------------------------
  846. //
  847. // Each object represents some action taken when a link in Control Panel is
  848. // selected. Actions are associated with links in the g_Link_XXXX declarations below.
  849. //
  850. //
  851. // NTRAID#NTBUG9-277853-2001/1/18-brianau Action disabled
  852. //
  853. // The "utility manager" task has been removed from the Control Panel UI.
  854. // I'm leaving the code in place in case the accessibility folks change their
  855. // minds. If by RC1 they haven't, remove this as well as the associated
  856. // text resources from shell32.rc
  857. //
  858. const CShellExecute g_LinkAction_32CtrlPanel (L"%SystemRoot%\\SysWOW64\\explorer.exe", L"/N,/SEPARATE,\"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\"", &g_Restrict32CtrlPanel);
  859. //const CShellExecute g_LinkAction_AccessUtilityMgr (L"utilman.exe", L"/start");
  860. const CShellExecute g_LinkAction_AccessWizard (L"%SystemRoot%\\System32\\accwiz.exe", NULL, &g_RestrictAccessWizard);
  861. const COpenUserMgrApplet g_LinkAction_Accounts (&g_RestrictUserManager);
  862. const COpenCplApplet g_LinkAction_AccountsChange (L"nusrmgr.cpl ,initialTask=ChangeAccount", &g_RestrictAccountsChange);
  863. const COpenCplApplet g_LinkAction_AccountsCreate (L"nusrmgr.cpl ,initialTask=CreateAccount", &g_RestrictAccountsCreate);
  864. const COpenCplApplet g_LinkAction_AccountsCreate2 (L"nusrmgr.cpl", &g_RestrictAccountsCreate2);
  865. const COpenCplApplet g_LinkAction_AccountsPict (L"nusrmgr.cpl ,initialTask=ChangePicture", &g_RestrictAccountsPicture);
  866. const CAddPrinter g_LinkAction_AddPrinter (&g_RestrictAddPrinter);
  867. const COpenCplApplet g_LinkAction_AddProgram (L"appwiz.cpl ,1", &g_RestrictArpAddProgram);
  868. const COpenCplApplet g_LinkAction_Arp (L"appwiz.cpl", &g_RestrictArp);
  869. const COpenCplApplet g_LinkAction_AutoUpdate (L"sysdm.cpl ,@wuaueng.dll,10000", &g_RestrictSystemCpl);
  870. const CExecDiskUtil g_LinkAction_BackupData (eDISKUTIL_BACKUP, &g_RestrictBackupData);
  871. const COpenCplCategory g_LinkAction_CatAccessibility (eCPCAT_ACCESSIBILITY);
  872. const COpenCplCategory2 g_LinkAction_CatAccounts (eCPCAT_ACCOUNTS, &g_LinkAction_Accounts);
  873. const COpenCplCategory g_LinkAction_CatAppearance (eCPCAT_APPEARANCE);
  874. const COpenCplCategory2 g_LinkAction_CatArp (eCPCAT_ARP, &g_LinkAction_Arp);
  875. const COpenCplCategory g_LinkAction_CatHardware (eCPCAT_HARDWARE);
  876. const COpenCplCategory g_LinkAction_CatNetwork (eCPCAT_NETWORK);
  877. const COpenCplCategory g_LinkAction_CatOther (eCPCAT_OTHER, &g_RestrictAlways);
  878. const COpenCplCategory g_LinkAction_CatPerfMaint (eCPCAT_PERFMAINT);
  879. const COpenCplCategory g_LinkAction_CatRegional (eCPCAT_REGIONAL);
  880. const COpenCplCategory g_LinkAction_CatSound (eCPCAT_SOUND);
  881. const CExecDiskUtil g_LinkAction_CleanUpDisk (eDISKUTIL_CLEANUP, &g_RestrictCleanUpDisk);
  882. const COpenCplApplet g_LinkAction_DateTime (L"timedate.cpl", &g_RestrictDateTime);
  883. const CExecDiskUtil g_LinkAction_Defrag (eDISKUTIL_DEFRAG, &g_RestrictDefrag);
  884. const COpenCplApplet g_LinkAction_DisplayCpl (L"desk.cpl", &g_RestrictDisplayCpl);
  885. const COpenDeskCpl g_LinkAction_DisplayRes (CPLTAB_DESK_SETTINGS, &g_RestrictResolution);
  886. const COpenCplApplet g_LinkAction_DisplayTheme (L"desk.cpl", &g_RestrictThemes);
  887. const CRunDll32 g_LinkAction_FolderOptions (L"shell32.dll,Options_RunDLL 0", &g_RestrictFolderOptions);
  888. const CNavigateURL g_LinkAction_FontsFolder (L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}", &g_RestrictFontsFolder);
  889. const COpenCplApplet g_LinkAction_HardwareWizard (L"hdwwiz.cpl", &g_RestrictHardwareWizard);
  890. const CTrayCommand g_LinkAction_HelpAndSupport (IDM_HELPSEARCH);
  891. const COpenCplApplet g_LinkAction_HighContrast (L"access.cpl ,3", &g_RestrictAccessibility);
  892. const CRunDll32 g_LinkAction_HomeNetWizard (L"hnetwiz.dll,HomeNetWizardRunDll", &g_RestrictHomeNetwork);
  893. const CShellExecute g_LinkAction_Magnifier (L"%SystemRoot%\\System32\\magnify.exe");
  894. const COpenCplApplet g_LinkAction_Language (L"intl.cpl ,1", &g_RestrictAddLanguage);
  895. const CNavigateURL g_LinkAction_LearnAccounts (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpWindowsAccounts.htm", &g_RestrictLearnAboutAccounts);
  896. const CNavigateURL g_LinkAction_LearnAccountsTypes (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpAccountTypes.htm", &g_RestrictLearnAboutAccountTypes);
  897. const CNavigateURL g_LinkAction_LearnAccountsChangeName (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpChangeNonAdmin.htm", &g_RestrictLearnAboutChangeName);
  898. const CNavigateURL g_LinkAction_LearnAccountsCreate (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpCreateAccount.htm", &g_RestrictLearnAboutCreateAccount);
  899. const CNavigateURL g_LinkAction_LearnSwitchUsers (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpFUS.htm", &g_RestrictLearnAboutFUS);
  900. const COpenCplApplet g_LinkAction_MousePointers (L"main.cpl ,2", &g_RestrictMousePointers);
  901. const CNavigateURL g_LinkAction_MyComputer (L"shell:DriveFolder");
  902. const CNavigateURL g_LinkAction_MyNetPlaces (L"shell:::{208D2C60-3AEA-1069-A2D7-08002B30309D}");
  903. const COpenCplApplet g_LinkAction_NetConnections (L"inetcpl.cpl ,4", &g_RestrictNetConnections);
  904. const CActionNYI g_LinkAction_NotYetImpl (L"Under construction");
  905. const CShellExecute g_LinkAction_OnScreenKbd (L"%SystemRoot%\\System32\\osk.exe");
  906. const COpenCplCategory g_LinkAction_OtherCplOptions (eCPCAT_OTHER, &g_RestrictOtherCplOptions);
  907. const COpenCplApplet g_LinkAction_PhoneModemCpl (L"telephon.cpl", &g_RestrictPhoneModemCpl);
  908. const COpenCplApplet g_LinkAction_PowerCpl (L"powercfg.cpl", &g_RestrictPowerOptions);
  909. const COpenCplApplet g_LinkAction_Region (L"intl.cpl", &g_RestrictInternational);
  910. const COpenCplApplet g_LinkAction_RemoteDesktop (L"sysdm.cpl ,@remotepg.dll,10000", &g_RestrictRemoteDesktop);
  911. const COpenCplApplet g_LinkAction_RemoveProgram (L"appwiz.cpl ,0", &g_RestrictArpRemoveProgram);
  912. const CNavigateURL g_LinkAction_ScheduledTasks (L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}", &g_RestrictScheduledTasks);
  913. const COpenDeskCpl g_LinkAction_ScreenSaver (CPLTAB_DESK_SCREENSAVER, &g_RestrictScreenSaver);
  914. const COpenCplApplet g_LinkAction_SoundAccessibility(L"access.cpl ,2", &g_RestrictAccessibility);
  915. const COpenCplCategory g_LinkAction_Sounds (eCPCAT_SOUND);
  916. const COpenCplApplet g_LinkAction_SoundSchemes (L"mmsys.cpl ,1", &g_RestrictSounds);
  917. const COpenCplApplet g_LinkAction_SoundVolume (L"mmsys.cpl ,0", &g_RestrictSounds);
  918. const CShellExecute g_LinkAction_SoundVolumeAdv (L"%SystemRoot%\\System32\\sndvol32.exe", NULL, &g_RestrictSounds);
  919. const COpenCplView g_LinkAction_SwToClassicView (eCPVIEWTYPE_CLASSIC);
  920. const COpenCplView g_LinkAction_SwToCategoryView (eCPVIEWTYPE_CATEGORY);
  921. const COpenCplApplet g_LinkAction_SystemCpl (L"sysdm.cpl ,@sysdm.cpl,10000", &g_RestrictSystemCpl);
  922. const CShellExecute g_LinkAction_SystemRestore (L"%SystemRoot%\\system32\\restore\\rstrui.exe", NULL, &g_RestrictSystemRestore);
  923. const COpenTroubleshooter g_LinkAction_TsDisplay (L"tsdisp.htm");
  924. const COpenTroubleshooter g_LinkAction_TsDvd (L"ts_dvd.htm");
  925. const COpenTroubleshooter g_LinkAction_TsHardware (L"tshardw.htm");
  926. const COpenTroubleshooter g_LinkAction_TsInetExplorer (L"tsie.htm", &g_RestrictTsInetExplorer);
  927. const COpenTroubleshooter g_LinkAction_TsModem (L"tsmodem.htm", &g_RestrictTsModem);
  928. const COpenTroubleshooter g_LinkAction_TsNetwork (L"tshomenet.htm", &g_RestrictTsNetworking);
  929. const CNavigateURL g_LinkAction_TsNetDiags (L"hcp://system/netdiag/dglogs.htm");
  930. const COpenTroubleshooter g_LinkAction_TsPrinting (L"tsprint.htm");
  931. const COpenTroubleshooter g_LinkAction_TsSharing (L"tssharing.htm", &g_RestrictTsSharing);
  932. const COpenTroubleshooter g_LinkAction_TsStartup (L"tsstartup.htm");
  933. const COpenTroubleshooter g_LinkAction_TsSound (L"tssound.htm");
  934. const CNavigateURL g_LinkAction_ViewPrinters (L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}", &g_RestrictPrinters);
  935. const COpenCplApplet g_LinkAction_VisualPerf (L"sysdm.cpl ,-1", &g_RestrictSystemCpl);
  936. const CRunDll32 g_LinkAction_VpnConnections (L"netshell.dll,StartNCW 21010", &g_RestrictVpnConnections);
  937. const COpenDeskCpl g_LinkAction_Wallpaper (CPLTAB_DESK_BACKGROUND, &g_RestrictWallpaper);
  938. const CNavigateURL g_LinkAction_WindowsUpdate (L"http://www.microsoft.com/isapi/redir.dll?prd=Win2000&ar=WinUpdate", &g_RestrictWindowsUpdate);
  939. //-----------------------------------------------------------------------------
  940. // Link object initialization data (alphabetical order please)
  941. //-----------------------------------------------------------------------------
  942. //
  943. // Each g_Link_XXXX variable represents a link in the Control Panel namespace.
  944. // Note that if a particular link is displayed in multiple places in the Control Panel,
  945. // only one instance of a g_Link_XXXX variable is required.
  946. //
  947. // The 'S' and 'T' in g_SLink and g_TLink mean "Support" and "Task" respectively.
  948. // I've used the generic term "support" to refer to items that appear in one
  949. // of the webview lists in the left-hand pane.
  950. // We may have a link in a support list and in a category task list that essentially
  951. // do the same thing but they have different icons and titles. The 'S' and 'T'
  952. // help differentiate.
  953. //
  954. const CResSrcStatic g_SLinkRes_32CtrlPanel_Icon(MAKEINTRESOURCEW(IDI_CPTASK_32CPLS));
  955. const CResSrcStatic g_SLinkRes_32CtrlPanel_Title(MAKEINTRESOURCEW(IDS_CPTASK_32CPLS_TITLE));
  956. const CResSrcStatic g_SLinkRes_32CtrlPanel_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_32CPLS_INFOTIP));
  957. const CPLINK_DESC g_SLink_32CtrlPanel = {
  958. &g_SLinkRes_32CtrlPanel_Icon,
  959. &g_SLinkRes_32CtrlPanel_Title,
  960. &g_SLinkRes_32CtrlPanel_Infotip,
  961. &g_LinkAction_32CtrlPanel
  962. };
  963. //
  964. // NTRAID#NTBUG9-277853-2001/1/18-brianau Action disabled
  965. //
  966. // The "utility manager" task has been removed from the Control Panel UI.
  967. // I'm leaving the code in place in case the accessibility folks change their
  968. // minds. If by RC1 they haven't, remove this as well as the associated
  969. // text resources from shell32.rc
  970. //
  971. #ifdef NEVER
  972. const CResSrcStatic g_SLinkRes_AccessUtilityMgr_Icon(MAKEINTRESOURCEW(IDI_CPTASK_ACCESSUTILITYMGR));
  973. const CResSrcStatic g_SLinkRes_AccessUtilityMgr_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCESSUTILITYMGR_TITLE));
  974. const CResSrcStatic g_SLinkRes_AccessUtilityMgr_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCESSUTILITYMGR_INFOTIP));
  975. const CPLINK_DESC g_SLink_AccessUtilityMgr = {
  976. &g_SLinkRes_AccessUtilityMgr_Icon,
  977. &g_SLinkRes_AccessUtilityMgr_Title,
  978. &g_SLinkRes_AccessUtilityMgr_Infotip,
  979. &g_LinkAction_AccessUtilityMgr
  980. };
  981. #endif
  982. const CResSrcStatic g_TLinkRes_AccessWizard_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  983. const CResSrcStatic g_TLinkRes_AccessWizard_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCESSWIZARD_TITLE));
  984. const CResSrcStatic g_TLinkRes_AccessWizard_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCESSWIZARD_INFOTIP));
  985. const CPLINK_DESC g_TLink_AccessWizard = {
  986. &g_TLinkRes_AccessWizard_Icon,
  987. &g_TLinkRes_AccessWizard_Title,
  988. &g_TLinkRes_AccessWizard_Infotip,
  989. &g_LinkAction_AccessWizard
  990. };
  991. const CResSrcStatic g_TLinkRes_AccountsChange_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  992. const CResSrcStatic g_TLinkRes_AccountsChange_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_TITLE));
  993. const CResSrcFunc g_TLinkRes_AccountsChange_Infotip(GetAccountsInfotip);
  994. const CPLINK_DESC g_TLink_AccountsChange = {
  995. &g_TLinkRes_AccountsChange_Icon,
  996. &g_TLinkRes_AccountsChange_Title,
  997. &g_TLinkRes_AccountsChange_Infotip,
  998. &g_LinkAction_AccountsChange
  999. };
  1000. const CResSrcStatic g_TLinkRes_AccountsCreate_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1001. const CResSrcStatic g_TLinkRes_AccountsCreate_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSCREATE_TITLE));
  1002. const CResSrcStatic g_TLinkRes_AccountsCreate_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSCREATE_INFOTIP));
  1003. const CPLINK_DESC g_TLink_AccountsCreate = {
  1004. &g_TLinkRes_AccountsCreate_Icon,
  1005. &g_TLinkRes_AccountsCreate_Title,
  1006. &g_TLinkRes_AccountsCreate_Infotip,
  1007. &g_LinkAction_AccountsCreate
  1008. };
  1009. //
  1010. // This link uses the same visual information as g_TLink_AccountsCreate above.
  1011. // The difference is in the action performed on selection.
  1012. //
  1013. const CPLINK_DESC g_TLink_AccountsCreate2 = {
  1014. &g_TLinkRes_AccountsCreate_Icon,
  1015. &g_TLinkRes_AccountsCreate_Title,
  1016. &g_TLinkRes_AccountsCreate_Infotip,
  1017. &g_LinkAction_AccountsCreate2
  1018. };
  1019. const CResSrcStatic g_SLinkRes_AccountsPict_Icon(L"nusrmgr.cpl,-205");
  1020. const CResSrcStatic g_SLinkRes_AccountsPict_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT_TITLE));
  1021. const CResSrcStatic g_SLinkRes_AccountsPict_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT_INFOTIP));
  1022. const CPLINK_DESC g_SLink_AccountsPict = {
  1023. &g_SLinkRes_AccountsPict_Icon,
  1024. &g_SLinkRes_AccountsPict_Title,
  1025. &g_SLinkRes_AccountsPict_Infotip,
  1026. &g_LinkAction_AccountsPict
  1027. };
  1028. const CResSrcStatic g_TLinkRes_AccountsPict_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1029. const CResSrcStatic g_TLinkRes_AccountsPict_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT2_TITLE));
  1030. const CResSrcStatic g_TLinkRes_AccountsPict_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT2_INFOTIP));
  1031. const CPLINK_DESC g_TLink_AccountsPict = {
  1032. &g_TLinkRes_AccountsPict_Icon,
  1033. &g_TLinkRes_AccountsPict_Title,
  1034. &g_TLinkRes_AccountsPict_Infotip,
  1035. &g_LinkAction_AccountsPict
  1036. };
  1037. const CResSrcStatic g_TLinkRes_Accounts_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1038. const CResSrcStatic g_TLinkRes_Accounts_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_TITLE));
  1039. const CResSrcFunc g_TLinkRes_Accounts_Infotip(GetAccountsInfotip);
  1040. const CPLINK_DESC g_TLink_Accounts = {
  1041. &g_TLinkRes_Accounts_Icon,
  1042. &g_TLinkRes_Accounts_Title,
  1043. &g_TLinkRes_Accounts_Infotip,
  1044. &g_LinkAction_Accounts
  1045. };
  1046. const CResSrcStatic g_TLinkRes_AddPrinter_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1047. const CResSrcStatic g_TLinkRes_AddPrinter_Title(MAKEINTRESOURCEW(IDS_CPTASK_ADDPRINTER_TITLE));
  1048. const CResSrcStatic g_TLinkRes_AddPrinter_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ADDPRINTER_INFOTIP));
  1049. const CPLINK_DESC g_TLink_AddPrinter = {
  1050. &g_TLinkRes_AddPrinter_Icon,
  1051. &g_TLinkRes_AddPrinter_Title,
  1052. &g_TLinkRes_AddPrinter_Infotip,
  1053. &g_LinkAction_AddPrinter
  1054. };
  1055. const CResSrcStatic g_TLinkRes_AddProgram_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1056. const CResSrcStatic g_TLinkRes_AddProgram_Title(MAKEINTRESOURCEW(IDS_CPTASK_ADDPROGRAM_TITLE));
  1057. const CResSrcStatic g_TLinkRes_AddProgram_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ADDPROGRAM_INFOTIP));
  1058. const CPLINK_DESC g_TLink_AddProgram = {
  1059. &g_TLinkRes_AddProgram_Icon,
  1060. &g_TLinkRes_AddProgram_Title,
  1061. &g_TLinkRes_AddProgram_Infotip,
  1062. &g_LinkAction_AddProgram
  1063. };
  1064. //
  1065. // Note that the "Auto Updates" icon is the same as the "Windows Update" icon.
  1066. // This is the way the Windows Update folks want it.
  1067. //
  1068. const CResSrcStatic g_SLinkRes_AutoUpdate_Icon(MAKEINTRESOURCEW(IDI_WINUPDATE));
  1069. const CResSrcStatic g_SLinkRes_AutoUpdate_Title(MAKEINTRESOURCEW(IDS_CPTASK_AUTOUPDATE_TITLE));
  1070. const CResSrcStatic g_SLinkRes_AutoUpdate_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_AUTOUPDATE_INFOTIP));
  1071. const CPLINK_DESC g_SLink_AutoUpdate = {
  1072. &g_SLinkRes_AutoUpdate_Icon,
  1073. &g_SLinkRes_AutoUpdate_Title,
  1074. &g_SLinkRes_AutoUpdate_Infotip,
  1075. &g_LinkAction_AutoUpdate
  1076. };
  1077. const CResSrcStatic g_TLinkRes_BackupData_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1078. const CResSrcStatic g_TLinkRes_BackupData_Title(MAKEINTRESOURCEW(IDS_CPTASK_BACKUPDATA_TITLE));
  1079. const CResSrcStatic g_TLinkRes_BackupData_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_BACKUPDATA_INFOTIP));
  1080. const CPLINK_DESC g_TLink_BackupData = {
  1081. &g_TLinkRes_BackupData_Icon,
  1082. &g_TLinkRes_BackupData_Title,
  1083. &g_TLinkRes_BackupData_Infotip,
  1084. &g_LinkAction_BackupData
  1085. };
  1086. const CResSrcStatic g_TLinkRes_CatAccessibility_Icon(MAKEINTRESOURCEW(IDI_CPCAT_ACCESSIBILITY));
  1087. const CResSrcStatic g_TLinkRes_CatAccessibility_Title(MAKEINTRESOURCEW(IDS_CPCAT_ACCESSIBILITY_TITLE));
  1088. const CResSrcStatic g_TLinkRes_CatAccessibility_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_ACCESSIBILITY_INFOTIP));
  1089. const CPLINK_DESC g_TLink_CatAccessibility = {
  1090. &g_TLinkRes_CatAccessibility_Icon,
  1091. &g_TLinkRes_CatAccessibility_Title,
  1092. &g_TLinkRes_CatAccessibility_Infotip,
  1093. &g_LinkAction_CatAccessibility
  1094. };
  1095. const CResSrcStatic g_TLinkRes_CatAccounts_Icon(MAKEINTRESOURCEW(IDI_CPCAT_ACCOUNTS));
  1096. const CResSrcStatic g_TLinkRes_CatAccounts_Title(MAKEINTRESOURCEW(IDS_CPCAT_ACCOUNTS_TITLE));
  1097. const CResSrcFunc g_TLinkRes_CatAccounts_Infotip(GetCatAccountsInfotip);
  1098. const CPLINK_DESC g_TLink_CatAccounts = {
  1099. &g_TLinkRes_CatAccounts_Icon,
  1100. &g_TLinkRes_CatAccounts_Title,
  1101. &g_TLinkRes_CatAccounts_Infotip,
  1102. &g_LinkAction_CatAccounts
  1103. };
  1104. const CResSrcStatic g_TLinkRes_CatAppearance_Icon(MAKEINTRESOURCEW(IDI_CPCAT_APPEARANCE));
  1105. const CResSrcStatic g_TLinkRes_CatAppearance_Title(MAKEINTRESOURCEW(IDS_CPCAT_APPEARANCE_TITLE));
  1106. const CResSrcStatic g_TLinkRes_CatAppearance_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_APPEARANCE_INFOTIP));
  1107. const CPLINK_DESC g_TLink_CatAppearance = {
  1108. &g_TLinkRes_CatAppearance_Icon,
  1109. &g_TLinkRes_CatAppearance_Title,
  1110. &g_TLinkRes_CatAppearance_Infotip,
  1111. &g_LinkAction_CatAppearance
  1112. };
  1113. const CResSrcStatic g_TLinkRes_CatArp_Icon(MAKEINTRESOURCEW(IDI_CPCAT_ARP));
  1114. const CResSrcStatic g_TLinkRes_CatArp_Title(MAKEINTRESOURCEW(IDS_CPCAT_ARP_TITLE));
  1115. const CResSrcStatic g_TLinkRes_CatArp_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_ARP_INFOTIP));
  1116. const CPLINK_DESC g_TLink_CatArp = {
  1117. &g_TLinkRes_CatArp_Icon,
  1118. &g_TLinkRes_CatArp_Title,
  1119. &g_TLinkRes_CatArp_Infotip,
  1120. &g_LinkAction_CatArp
  1121. };
  1122. const CResSrcStatic g_TLinkRes_CatHardware_Icon(MAKEINTRESOURCEW(IDI_CPCAT_HARDWARE));
  1123. const CResSrcStatic g_TLinkRes_CatHardware_Title(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_TITLE));
  1124. const CResSrcStatic g_TLinkRes_CatHardware_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_INFOTIP));
  1125. const CPLINK_DESC g_TLink_CatHardware = {
  1126. &g_TLinkRes_CatHardware_Icon,
  1127. &g_TLinkRes_CatHardware_Title,
  1128. &g_TLinkRes_CatHardware_Infotip,
  1129. &g_LinkAction_CatHardware
  1130. };
  1131. const CResSrcStatic g_TLinkRes_CatNetwork_Icon(MAKEINTRESOURCEW(IDI_CPCAT_NETWORK));
  1132. const CResSrcStatic g_TLinkRes_CatNetwork_Title(MAKEINTRESOURCEW(IDS_CPCAT_NETWORK_TITLE));
  1133. const CResSrcStatic g_TLinkRes_CatNetwork_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_NETWORK_INFOTIP));
  1134. const CPLINK_DESC g_TLink_CatNetwork = {
  1135. &g_TLinkRes_CatNetwork_Icon,
  1136. &g_TLinkRes_CatNetwork_Title,
  1137. &g_TLinkRes_CatNetwork_Infotip,
  1138. &g_LinkAction_CatNetwork
  1139. };
  1140. const CResSrcStatic g_TLinkRes_CatOther_Icon(MAKEINTRESOURCEW(IDI_CPCAT_OTHERCPLS));
  1141. const CResSrcStatic g_TLinkRes_CatOther_Title(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_TITLE));
  1142. const CResSrcStatic g_TLinkRes_CatOther_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_INFOTIP));
  1143. const CPLINK_DESC g_TLink_CatOther = {
  1144. &g_TLinkRes_CatOther_Icon,
  1145. &g_TLinkRes_CatOther_Title,
  1146. &g_TLinkRes_CatOther_Infotip,
  1147. &g_LinkAction_CatOther
  1148. };
  1149. const CResSrcStatic g_TLinkRes_CatPerfMaint_Icon(MAKEINTRESOURCEW(IDI_CPCAT_PERFMAINT));
  1150. const CResSrcStatic g_TLinkRes_CatPerfMaint_Title(MAKEINTRESOURCEW(IDS_CPCAT_PERFMAINT_TITLE));
  1151. const CResSrcStatic g_TLinkRes_CatPerfMaint_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_PERFMAINT_INFOTIP));
  1152. const CPLINK_DESC g_TLink_CatPerfMaint = {
  1153. &g_TLinkRes_CatPerfMaint_Icon,
  1154. &g_TLinkRes_CatPerfMaint_Title,
  1155. &g_TLinkRes_CatPerfMaint_Infotip,
  1156. &g_LinkAction_CatPerfMaint
  1157. };
  1158. const CResSrcStatic g_TLinkRes_CatRegional_Icon(MAKEINTRESOURCEW(IDI_CPCAT_REGIONAL));
  1159. const CResSrcStatic g_TLinkRes_CatRegional_Title(MAKEINTRESOURCEW(IDS_CPCAT_REGIONAL_TITLE));
  1160. const CResSrcStatic g_TLinkRes_CatRegional_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_REGIONAL_INFOTIP));
  1161. const CPLINK_DESC g_TLink_CatRegional = {
  1162. &g_TLinkRes_CatRegional_Icon,
  1163. &g_TLinkRes_CatRegional_Title,
  1164. &g_TLinkRes_CatRegional_Infotip,
  1165. &g_LinkAction_CatRegional
  1166. };
  1167. const CResSrcStatic g_TLinkRes_CatSound_Icon(MAKEINTRESOURCEW(IDI_CPCAT_SOUNDS));
  1168. const CResSrcStatic g_TLinkRes_CatSound_Title(MAKEINTRESOURCEW(IDS_CPCAT_SOUNDS_TITLE));
  1169. const CResSrcStatic g_TLinkRes_CatSound_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_SOUNDS_INFOTIP));
  1170. const CPLINK_DESC g_TLink_CatSound = {
  1171. &g_TLinkRes_CatSound_Icon,
  1172. &g_TLinkRes_CatSound_Title,
  1173. &g_TLinkRes_CatSound_Infotip,
  1174. &g_LinkAction_CatSound
  1175. };
  1176. const CResSrcStatic g_TLinkRes_CleanUpDisk_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1177. const CResSrcStatic g_TLinkRes_CleanUpDisk_Title(MAKEINTRESOURCEW(IDS_CPTASK_CLEANUPDISK_TITLE));
  1178. const CResSrcStatic g_TLinkRes_CleanUpDisk_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_CLEANUPDISK_INFOTIP));
  1179. const CPLINK_DESC g_TLink_CleanUpDisk = {
  1180. &g_TLinkRes_CleanUpDisk_Icon,
  1181. &g_TLinkRes_CleanUpDisk_Title,
  1182. &g_TLinkRes_CleanUpDisk_Infotip,
  1183. &g_LinkAction_CleanUpDisk
  1184. };
  1185. const CResSrcStatic g_TLinkRes_DateTime_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1186. const CResSrcStatic g_TLinkRes_DateTime_Title(MAKEINTRESOURCEW(IDS_CPTASK_DATETIME_TITLE));
  1187. const CResSrcStatic g_TLinkRes_DateTime_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_DATETIME_INFOTIP));
  1188. const CPLINK_DESC g_TLink_DateTime = {
  1189. &g_TLinkRes_DateTime_Icon,
  1190. &g_TLinkRes_DateTime_Title,
  1191. &g_TLinkRes_DateTime_Infotip,
  1192. &g_LinkAction_DateTime
  1193. };
  1194. const CResSrcStatic g_TLinkRes_Defrag_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1195. const CResSrcStatic g_TLinkRes_Defrag_Title(MAKEINTRESOURCEW(IDS_CPTASK_DEFRAG_TITLE));
  1196. const CResSrcStatic g_TLinkRes_Defrag_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_DEFRAG_INFOTIP));
  1197. const CPLINK_DESC g_TLink_Defrag = {
  1198. &g_TLinkRes_Defrag_Icon,
  1199. &g_TLinkRes_Defrag_Title,
  1200. &g_TLinkRes_Defrag_Infotip,
  1201. &g_LinkAction_Defrag
  1202. };
  1203. const CResSrcStatic g_SLinkRes_DisplayCpl_Icon(L"desk.cpl,0");
  1204. const CResSrcStatic g_SLinkRes_DisplayCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_DISPLAYCPL_TITLE));
  1205. const CResSrcStatic g_SLinkRes_DisplayCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_DISPLAYCPL_INFOTIP));
  1206. const CPLINK_DESC g_SLink_DisplayCpl = {
  1207. &g_SLinkRes_DisplayCpl_Icon,
  1208. &g_SLinkRes_DisplayCpl_Title,
  1209. &g_SLinkRes_DisplayCpl_Infotip,
  1210. &g_LinkAction_DisplayCpl
  1211. };
  1212. const CResSrcStatic g_TLinkRes_DisplayRes_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1213. const CResSrcStatic g_TLinkRes_DisplayRes_Title(MAKEINTRESOURCEW(IDS_CPTASK_RESOLUTION_TITLE));
  1214. const CResSrcStatic g_TLinkRes_DisplayRes_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_RESOLUTION_INFOTIP));
  1215. const CPLINK_DESC g_TLink_DisplayRes = {
  1216. &g_TLinkRes_DisplayRes_Icon,
  1217. &g_TLinkRes_DisplayRes_Title,
  1218. &g_TLinkRes_DisplayRes_Infotip,
  1219. &g_LinkAction_DisplayRes
  1220. };
  1221. const CResSrcStatic g_TLinkRes_DisplayTheme_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1222. const CResSrcStatic g_TLinkRes_DisplayTheme_Title(MAKEINTRESOURCEW(IDS_CPTASK_THEME_TITLE));
  1223. const CResSrcStatic g_TLinkRes_DisplayTheme_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_THEME_INFOTIP));
  1224. const CPLINK_DESC g_TLink_DisplayTheme = {
  1225. &g_TLinkRes_DisplayTheme_Icon,
  1226. &g_TLinkRes_DisplayTheme_Title,
  1227. &g_TLinkRes_DisplayTheme_Infotip,
  1228. &g_LinkAction_DisplayTheme
  1229. };
  1230. const CResSrcStatic g_SLinkRes_FileTypes_Icon(MAKEINTRESOURCEW(IDI_FOLDEROPTIONS));
  1231. const CResSrcStatic g_SLinkRes_FileTypes_Title(MAKEINTRESOURCEW(IDS_CPTASK_FILETYPES_TITLE));
  1232. const CResSrcStatic g_SLinkRes_FileTypes_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_FILETYPES_INFOTIP));
  1233. const CPLINK_DESC g_SLink_FileTypes = {
  1234. &g_SLinkRes_FileTypes_Icon,
  1235. &g_SLinkRes_FileTypes_Title,
  1236. &g_SLinkRes_FileTypes_Infotip,
  1237. &g_LinkAction_FolderOptions
  1238. };
  1239. const CResSrcStatic g_TLinkRes_FolderOptions_Icon(MAKEINTRESOURCEW(IDI_FOLDEROPTIONS));
  1240. const CResSrcStatic g_TLinkRes_FolderOptions_Title(MAKEINTRESOURCEW(IDS_CPTASK_FOLDEROPTIONS_TITLE));
  1241. const CResSrcStatic g_TLinkRes_FolderOptions_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_FOLDEROPTIONS_INFOTIP));
  1242. const CPLINK_DESC g_SLink_FolderOptions = {
  1243. &g_TLinkRes_FolderOptions_Icon,
  1244. &g_TLinkRes_FolderOptions_Title,
  1245. &g_TLinkRes_FolderOptions_Infotip,
  1246. &g_LinkAction_FolderOptions
  1247. };
  1248. const CResSrcStatic g_SLinkRes_FontsFolder_Icon(MAKEINTRESOURCEW(IDI_STFONTS));
  1249. const CResSrcStatic g_SLinkRes_FontsFolder_Title(MAKEINTRESOURCEW(IDS_CPTASK_FONTS_TITLE));
  1250. const CResSrcStatic g_SLinkRes_FontsFolder_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_FONTS_INFOTIP));
  1251. const CPLINK_DESC g_SLink_FontsFolder = {
  1252. &g_SLinkRes_FontsFolder_Icon,
  1253. &g_SLinkRes_FontsFolder_Title,
  1254. &g_SLinkRes_FontsFolder_Infotip,
  1255. &g_LinkAction_FontsFolder
  1256. };
  1257. const CResSrcStatic g_SLinkRes_Hardware_Icon(MAKEINTRESOURCEW(IDI_CPCAT_HARDWARE));
  1258. const CResSrcStatic g_SLinkRes_Hardware_Title(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_TITLE));
  1259. const CResSrcStatic g_SLinkRes_Hardware_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_INFOTIP));
  1260. const CPLINK_DESC g_SLink_Hardware = {
  1261. &g_SLinkRes_Hardware_Icon,
  1262. &g_SLinkRes_Hardware_Title,
  1263. &g_SLinkRes_Hardware_Infotip,
  1264. &g_LinkAction_CatHardware
  1265. };
  1266. const CResSrcStatic g_SLinkRes_HardwareWizard_Icon(L"hdwwiz.cpl,0");
  1267. const CResSrcStatic g_SLinkRes_HardwareWizard_Title(MAKEINTRESOURCEW(IDS_CPTASK_HARDWAREWIZ_TITLE));
  1268. const CResSrcStatic g_SLinkRes_HardwareWizard_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HARDWAREWIZ_INFOTIP));
  1269. const CPLINK_DESC g_SLink_HardwareWizard = {
  1270. &g_SLinkRes_HardwareWizard_Icon,
  1271. &g_SLinkRes_HardwareWizard_Title,
  1272. &g_SLinkRes_HardwareWizard_Infotip,
  1273. &g_LinkAction_HardwareWizard
  1274. };
  1275. const CResSrcStatic g_SLinkRes_HelpAndSupport_Icon(MAKEINTRESOURCEW(IDI_STHELP));
  1276. const CResSrcStatic g_SLinkRes_HelpAndSupport_Title(MAKEINTRESOURCEW(IDS_CPTASK_HELPANDSUPPORT_TITLE));
  1277. const CResSrcStatic g_SLinkRes_HelpAndSupport_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HELPANDSUPPORT_INFOTIP));
  1278. const CPLINK_DESC g_SLink_HelpAndSupport = {
  1279. &g_SLinkRes_HelpAndSupport_Icon,
  1280. &g_SLinkRes_HelpAndSupport_Title,
  1281. &g_SLinkRes_HelpAndSupport_Infotip,
  1282. &g_LinkAction_HelpAndSupport
  1283. };
  1284. const CResSrcStatic g_SLinkRes_HighContrast_Icon(MAKEINTRESOURCEW(IDI_CPTASK_HIGHCONTRAST));
  1285. const CResSrcStatic g_SLinkRes_HighContrast_Title(MAKEINTRESOURCEW(IDS_CPTASK_HIGHCONTRAST_TITLE));
  1286. const CResSrcStatic g_SLinkRes_HighContrast_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HIGHCONTRAST_INFOTIP));
  1287. const CPLINK_DESC g_SLink_HighContrast = {
  1288. &g_SLinkRes_HighContrast_Icon,
  1289. &g_SLinkRes_HighContrast_Title,
  1290. &g_SLinkRes_HighContrast_Infotip,
  1291. &g_LinkAction_HighContrast
  1292. };
  1293. const CResSrcStatic g_TLinkRes_HighContrast_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1294. const CResSrcStatic g_TLinkRes_HighContrast_Title(MAKEINTRESOURCEW(IDS_CPTASK_TURNONHIGHCONTRAST_TITLE));
  1295. const CResSrcStatic g_TLinkRes_HighContrast_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TURNONHIGHCONTRAST_INFOTIP));
  1296. const CPLINK_DESC g_TLink_HighContrast = {
  1297. &g_TLinkRes_HighContrast_Icon,
  1298. &g_TLinkRes_HighContrast_Title,
  1299. &g_TLinkRes_HighContrast_Infotip,
  1300. &g_LinkAction_HighContrast
  1301. };
  1302. const CResSrcStatic g_TLinkRes_HomeNetWizard_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1303. const CResSrcStatic g_TLinkRes_HomeNetWizard_Title(MAKEINTRESOURCEW(IDS_CPTASK_HOMENETWORK_TITLE));
  1304. const CResSrcStatic g_TLinkRes_HomeNetWizard_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HOMENETWORK_INFOTIP));
  1305. const CPLINK_DESC g_TLink_HomeNetWizard = {
  1306. &g_TLinkRes_HomeNetWizard_Icon,
  1307. &g_TLinkRes_HomeNetWizard_Title,
  1308. &g_TLinkRes_HomeNetWizard_Infotip,
  1309. &g_LinkAction_HomeNetWizard
  1310. };
  1311. const CResSrcStatic g_TLinkRes_Language_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1312. const CResSrcStatic g_TLinkRes_Language_Title(MAKEINTRESOURCEW(IDS_CPTASK_LANGUAGE_TITLE));
  1313. const CResSrcStatic g_TLinkRes_Language_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_LANGUAGE_INFOTIP));
  1314. const CPLINK_DESC g_TLink_Language = {
  1315. &g_TLinkRes_Language_Icon,
  1316. &g_TLinkRes_Language_Title,
  1317. &g_TLinkRes_Language_Infotip,
  1318. &g_LinkAction_Language
  1319. };
  1320. //
  1321. // Learn-about topics use a standard icon and have no infotip.
  1322. //
  1323. const CResSrcStatic g_SLinkRes_LearnAbout_Icon(MAKEINTRESOURCE(IDI_CPTASK_LEARNABOUT));
  1324. const CResSrcNone g_SLinkRes_LearnAbout_Infotip;
  1325. const CResSrcStatic g_SLinkRes_LearnAccounts_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTS_TITLE));
  1326. const CPLINK_DESC g_SLink_LearnAccounts = {
  1327. &g_SLinkRes_LearnAbout_Icon,
  1328. &g_SLinkRes_LearnAccounts_Title,
  1329. &g_SLinkRes_LearnAbout_Infotip,
  1330. &g_LinkAction_LearnAccounts
  1331. };
  1332. const CResSrcStatic g_SLinkRes_LearnAccountsTypes_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTSTYPES_TITLE));
  1333. const CPLINK_DESC g_SLink_LearnAccountsTypes = {
  1334. &g_SLinkRes_LearnAbout_Icon,
  1335. &g_SLinkRes_LearnAccountsTypes_Title,
  1336. &g_SLinkRes_LearnAbout_Infotip,
  1337. &g_LinkAction_LearnAccountsTypes
  1338. };
  1339. const CResSrcStatic g_SLinkRes_LearnAccountsChangeName_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTSCHANGENAME_TITLE));
  1340. const CPLINK_DESC g_SLink_LearnAccountsChangeName = {
  1341. &g_SLinkRes_LearnAbout_Icon,
  1342. &g_SLinkRes_LearnAccountsChangeName_Title,
  1343. &g_SLinkRes_LearnAbout_Infotip,
  1344. &g_LinkAction_LearnAccountsChangeName
  1345. };
  1346. const CResSrcStatic g_SLinkRes_LearnAccountsCreate_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTSCREATE_TITLE));
  1347. const CPLINK_DESC g_SLink_LearnAccountsCreate = {
  1348. &g_SLinkRes_LearnAbout_Icon,
  1349. &g_SLinkRes_LearnAccountsCreate_Title,
  1350. &g_SLinkRes_LearnAbout_Infotip,
  1351. &g_LinkAction_LearnAccountsCreate
  1352. };
  1353. const CResSrcStatic g_SLinkRes_LearnSwitchUsers_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNSWITCHUSERS_TITLE));
  1354. const CPLINK_DESC g_SLink_LearnSwitchUsers = {
  1355. &g_SLinkRes_LearnAbout_Icon,
  1356. &g_SLinkRes_LearnSwitchUsers_Title,
  1357. &g_SLinkRes_LearnAbout_Infotip,
  1358. &g_LinkAction_LearnSwitchUsers
  1359. };
  1360. const CResSrcStatic g_SLinkRes_Magnifier_Icon(MAKEINTRESOURCEW(IDI_CPTASK_MAGNIFIER));
  1361. const CResSrcStatic g_SLinkRes_Magnifier_Title(MAKEINTRESOURCEW(IDS_CPTASK_MAGNIFIER_TITLE));
  1362. const CResSrcStatic g_SLinkRes_Magnifier_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MAGNIFIER_INFOTIP));
  1363. const CPLINK_DESC g_SLink_Magnifier = {
  1364. &g_SLinkRes_Magnifier_Icon,
  1365. &g_SLinkRes_Magnifier_Title,
  1366. &g_SLinkRes_Magnifier_Infotip,
  1367. &g_LinkAction_Magnifier
  1368. };
  1369. const CResSrcStatic g_SLinkRes_MousePointers_Icon(L"main.cpl,0");
  1370. const CResSrcStatic g_SLinkRes_MousePointers_Title(MAKEINTRESOURCEW(IDS_CPTASK_MOUSEPOINTERS_TITLE));
  1371. const CResSrcStatic g_SLinkRes_MousePointers_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MOUSEPOINTERS_INFOTIP));
  1372. const CPLINK_DESC g_SLink_MousePointers = {
  1373. &g_SLinkRes_MousePointers_Icon,
  1374. &g_SLinkRes_MousePointers_Title,
  1375. &g_SLinkRes_MousePointers_Infotip,
  1376. &g_LinkAction_MousePointers
  1377. };
  1378. const CResSrcStatic g_SLinkRes_MyComputer_Icon(L"explorer.exe,0");
  1379. const CResSrcStatic g_SLinkRes_MyComputer_Title(MAKEINTRESOURCEW(IDS_CPTASK_MYCOMPUTER_TITLE));
  1380. const CResSrcStatic g_SLinkRes_MyComputer_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MYCOMPUTER_INFOTIP));
  1381. const CPLINK_DESC g_SLink_MyComputer = {
  1382. &g_SLinkRes_MyComputer_Icon,
  1383. &g_SLinkRes_MyComputer_Title,
  1384. &g_SLinkRes_MyComputer_Infotip,
  1385. &g_LinkAction_MyComputer
  1386. };
  1387. const CResSrcStatic g_SLinkRes_MyNetPlaces_Icon(MAKEINTRESOURCEW(IDI_NETCONNECT));
  1388. const CResSrcStatic g_SLinkRes_MyNetPlaces_Title(MAKEINTRESOURCEW(IDS_CPTASK_MYNETPLACES_TITLE));
  1389. const CResSrcStatic g_SLinkRes_MyNetPlaces_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MYNETPLACES_INFOTIP));
  1390. const CPLINK_DESC g_SLink_MyNetPlaces = {
  1391. &g_SLinkRes_MyNetPlaces_Icon,
  1392. &g_SLinkRes_MyNetPlaces_Title,
  1393. &g_SLinkRes_MyNetPlaces_Infotip,
  1394. &g_LinkAction_MyNetPlaces
  1395. };
  1396. const CResSrcStatic g_TLinkRes_NetConnections_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1397. const CResSrcStatic g_TLinkRes_NetConnections_Title(MAKEINTRESOURCEW(IDS_CPTASK_NETCONNECTION_TITLE));
  1398. const CResSrcStatic g_TLinkRes_NetConnections_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_NETCONNECTION_INFOTIP));
  1399. const CPLINK_DESC g_TLink_NetConnections = {
  1400. &g_TLinkRes_NetConnections_Icon,
  1401. &g_TLinkRes_NetConnections_Title,
  1402. &g_TLinkRes_NetConnections_Infotip,
  1403. &g_LinkAction_NetConnections
  1404. };
  1405. const CResSrcStatic g_SLinkRes_OnScreenKbd_Icon(MAKEINTRESOURCEW(IDI_CPTASK_ONSCREENKBD));
  1406. const CResSrcStatic g_SLinkRes_OnScreenKbd_Title(MAKEINTRESOURCEW(IDS_CPTASK_ONSCREENKBD_TITLE));
  1407. const CResSrcStatic g_SLinkRes_OnScreenKbd_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ONSCREENKBD_INFOTIP));
  1408. const CPLINK_DESC g_SLink_OnScreenKbd = {
  1409. &g_SLinkRes_OnScreenKbd_Icon,
  1410. &g_SLinkRes_OnScreenKbd_Title,
  1411. &g_SLinkRes_OnScreenKbd_Infotip,
  1412. &g_LinkAction_OnScreenKbd
  1413. };
  1414. const CResSrcStatic g_SLinkRes_OtherCplOptions_Icon(MAKEINTRESOURCEW(IDI_CPCAT_OTHERCPLS));
  1415. const CResSrcStatic g_SLinkRes_OtherCplOptions_Title(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_TITLE));
  1416. const CResSrcStatic g_SLinkRes_OtherCplOptions_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_INFOTIP));
  1417. const CPLINK_DESC g_SLink_OtherCplOptions = {
  1418. &g_SLinkRes_OtherCplOptions_Icon,
  1419. &g_SLinkRes_OtherCplOptions_Title,
  1420. &g_SLinkRes_OtherCplOptions_Infotip,
  1421. &g_LinkAction_OtherCplOptions
  1422. };
  1423. const CResSrcStatic g_SLinkRes_PhoneModemCpl_Icon(L"telephon.cpl,0");
  1424. const CResSrcStatic g_SLinkRes_PhoneModemCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_PHONEMODEMCPL_TITLE));
  1425. const CResSrcStatic g_SLinkRes_PhoneModemCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_PHONEMODEMCPL_INFOTIP));
  1426. const CPLINK_DESC g_SLink_PhoneModemCpl = {
  1427. &g_SLinkRes_PhoneModemCpl_Icon,
  1428. &g_SLinkRes_PhoneModemCpl_Title,
  1429. &g_SLinkRes_PhoneModemCpl_Infotip,
  1430. &g_LinkAction_PhoneModemCpl
  1431. };
  1432. const CResSrcStatic g_SLinkRes_PowerCpl_Icon(L"powercfg.cpl,-202");
  1433. const CResSrcStatic g_SLinkRes_PowerCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_POWERCPL_TITLE));
  1434. const CResSrcStatic g_SLinkRes_PowerCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_POWERCPL_INFOTIP));
  1435. const CPLINK_DESC g_SLink_PowerCpl = {
  1436. &g_SLinkRes_PowerCpl_Icon,
  1437. &g_SLinkRes_PowerCpl_Title,
  1438. &g_SLinkRes_PowerCpl_Infotip,
  1439. &g_LinkAction_PowerCpl
  1440. };
  1441. const CResSrcStatic g_TLinkRes_Region_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1442. const CResSrcStatic g_TLinkRes_Region_Title(MAKEINTRESOURCEW(IDS_CPTASK_CHANGEREGION_TITLE));
  1443. const CResSrcStatic g_TLinkRes_Region_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_CHANGEREGION_INFOTIP));
  1444. const CPLINK_DESC g_TLink_Region = {
  1445. &g_TLinkRes_Region_Icon,
  1446. &g_TLinkRes_Region_Title,
  1447. &g_TLinkRes_Region_Infotip,
  1448. &g_LinkAction_Region
  1449. };
  1450. const CResSrcStatic g_SLinkRes_RemoteDesktop_Icon(L"remotepg.dll,0");
  1451. const CResSrcStatic g_SLinkRes_RemoteDesktop_Title(MAKEINTRESOURCEW(IDS_CPTASK_REMOTEDESKTOP_TITLE));
  1452. const CResSrcStatic g_SLinkRes_RemoteDesktop_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_REMOTEDESKTOP_INFOTIP));
  1453. const CPLINK_DESC g_SLink_RemoteDesktop = {
  1454. &g_SLinkRes_RemoteDesktop_Icon,
  1455. &g_SLinkRes_RemoteDesktop_Title,
  1456. &g_SLinkRes_RemoteDesktop_Infotip,
  1457. &g_LinkAction_RemoteDesktop
  1458. };
  1459. const CResSrcStatic g_TLinkRes_RemoveProgram_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1460. const CResSrcStatic g_TLinkRes_RemoveProgram_Title(MAKEINTRESOURCEW(IDS_CPTASK_REMOVEPROGRAM_TITLE));
  1461. const CResSrcStatic g_TLinkRes_RemoveProgram_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_REMOVEPROGRAM_INFOTIP));
  1462. const CPLINK_DESC g_TLink_RemoveProgram = {
  1463. &g_TLinkRes_RemoveProgram_Icon,
  1464. &g_TLinkRes_RemoveProgram_Title,
  1465. &g_TLinkRes_RemoveProgram_Infotip,
  1466. &g_LinkAction_RemoveProgram
  1467. };
  1468. const CResSrcStatic g_TLinkRes_ScreenSaver_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1469. const CResSrcStatic g_TLinkRes_ScreenSaver_Title(MAKEINTRESOURCE(IDS_CPTASK_SCREENSAVER_TITLE));
  1470. const CResSrcStatic g_TLinkRes_ScreenSaver_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SCREENSAVER_INFOTIP));
  1471. const CPLINK_DESC g_TLink_ScreenSaver = {
  1472. &g_TLinkRes_ScreenSaver_Icon,
  1473. &g_TLinkRes_ScreenSaver_Title,
  1474. &g_TLinkRes_ScreenSaver_Infotip,
  1475. &g_LinkAction_ScreenSaver
  1476. };
  1477. const CResSrcStatic g_SLinkRes_ScheduledTasks_Icon(L"mstask.dll,-100");
  1478. const CResSrcStatic g_SLinkRes_ScheduledTasks_Title(MAKEINTRESOURCEW(IDS_CPTASK_SCHEDULEDTASKS_TITLE));
  1479. const CResSrcStatic g_SLinkRes_ScheduledTasks_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SCHEDULEDTASKS_INFOTIP));
  1480. const CPLINK_DESC g_SLink_ScheduledTasks = {
  1481. &g_SLinkRes_ScheduledTasks_Icon,
  1482. &g_SLinkRes_ScheduledTasks_Title,
  1483. &g_SLinkRes_ScheduledTasks_Infotip,
  1484. &g_LinkAction_ScheduledTasks
  1485. };
  1486. const CResSrcStatic g_SLinkRes_Sounds_Icon(L"mmsys.cpl,0");
  1487. const CResSrcStatic g_SLinkRes_Sounds_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCPL_TITLE));
  1488. const CResSrcStatic g_SLinkRes_Sounds_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCPL_INFOTIP));
  1489. const CPLINK_DESC g_SLink_Sounds = {
  1490. &g_SLinkRes_Sounds_Icon,
  1491. &g_SLinkRes_Sounds_Title,
  1492. &g_SLinkRes_Sounds_Infotip,
  1493. &g_LinkAction_Sounds
  1494. };
  1495. const CResSrcStatic g_SLinkRes_SoundAccessibility_Icon(L"mmsys.cpl,0");
  1496. const CResSrcStatic g_SLinkRes_SoundAccessibility_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDACCESSIBILITY_TITLE));
  1497. const CResSrcStatic g_SLinkRes_SoundAccessibility_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDACCESSIBILITY_INFOTIP));
  1498. const CPLINK_DESC g_SLink_SoundAccessibility = {
  1499. &g_SLinkRes_SoundAccessibility_Icon,
  1500. &g_SLinkRes_SoundAccessibility_Title,
  1501. &g_SLinkRes_SoundAccessibility_Infotip,
  1502. &g_LinkAction_SoundAccessibility
  1503. };
  1504. const CResSrcStatic g_TLinkRes_SoundSchemes_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1505. const CResSrcStatic g_TLinkRes_SoundSchemes_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCHEMES_TITLE));
  1506. const CResSrcStatic g_TLinkRes_SoundSchemes_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCHEMES_INFOTIP));
  1507. const CPLINK_DESC g_TLink_SoundSchemes = {
  1508. &g_TLinkRes_SoundSchemes_Icon,
  1509. &g_TLinkRes_SoundSchemes_Title,
  1510. &g_TLinkRes_SoundSchemes_Infotip,
  1511. &g_LinkAction_SoundSchemes
  1512. };
  1513. const CResSrcStatic g_TLinkRes_SoundVolume_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1514. const CResSrcStatic g_TLinkRes_SoundVolume_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUME_TITLE));
  1515. const CResSrcStatic g_TLinkRes_SoundVolume_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUME_INFOTIP));
  1516. const CPLINK_DESC g_TLink_SoundVolume = {
  1517. &g_TLinkRes_SoundVolume_Icon,
  1518. &g_TLinkRes_SoundVolume_Title,
  1519. &g_TLinkRes_SoundVolume_Infotip,
  1520. &g_LinkAction_SoundVolume
  1521. };
  1522. const CResSrcStatic g_SLinkRes_SoundVolumeAdv_Icon(L"sndvol32.exe,-300");
  1523. const CResSrcStatic g_SLinkRes_SoundVolumeAdv_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUMEADV_TITLE));
  1524. const CResSrcStatic g_SLinkRes_SoundVolumeAdv_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUMEADV_INFOTIP));
  1525. const CPLINK_DESC g_SLink_SoundVolumeAdv = {
  1526. &g_SLinkRes_SoundVolumeAdv_Icon,
  1527. &g_SLinkRes_SoundVolumeAdv_Title,
  1528. &g_SLinkRes_SoundVolumeAdv_Infotip,
  1529. &g_LinkAction_SoundVolumeAdv
  1530. };
  1531. const CResSrcStatic g_TLinkRes_SpeakerSettings_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1532. const CResSrcStatic g_TLinkRes_SpeakerSettings_Title(MAKEINTRESOURCEW(IDS_CPTASK_SPEAKERSETTINGS_TITLE));
  1533. const CResSrcStatic g_TLinkRes_SpeakerSettings_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SPEAKERSETTINGS_INFOTIP));
  1534. const CPLINK_DESC g_TLink_SpeakerSettings = {
  1535. &g_TLinkRes_SpeakerSettings_Icon,
  1536. &g_TLinkRes_SpeakerSettings_Title,
  1537. &g_TLinkRes_SpeakerSettings_Infotip,
  1538. &g_LinkAction_SoundVolume
  1539. };
  1540. const CResSrcStatic g_SLinkRes_SystemCpl_Icon(L"sysdm.cpl,0");
  1541. const CResSrcStatic g_SLinkRes_SystemCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_TITLE));
  1542. const CResSrcStatic g_SLinkRes_SystemCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_INFOTIP));
  1543. const CPLINK_DESC g_SLink_SystemCpl = {
  1544. &g_SLinkRes_SystemCpl_Icon,
  1545. &g_SLinkRes_SystemCpl_Title,
  1546. &g_SLinkRes_SystemCpl_Infotip,
  1547. &g_LinkAction_SystemCpl
  1548. };
  1549. const CResSrcStatic g_TLinkRes_SystemCpl_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1550. const CResSrcStatic g_TLinkRes_SystemCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_TITLE2));
  1551. const CResSrcStatic g_TLinkRes_SystemCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_INFOTIP2));
  1552. const CPLINK_DESC g_TLink_SystemCpl = {
  1553. &g_TLinkRes_SystemCpl_Icon,
  1554. &g_TLinkRes_SystemCpl_Title,
  1555. &g_TLinkRes_SystemCpl_Infotip,
  1556. &g_LinkAction_SystemCpl
  1557. };
  1558. const CResSrcStatic g_SLinkRes_SystemRestore_Icon(L"%systemroot%\\system32\\restore\\rstrui.exe,0");
  1559. const CResSrcStatic g_SLinkRes_SystemRestore_Title(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMRESTORE_TITLE));
  1560. const CResSrcStatic g_SLinkRes_SystemRestore_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMRESTORE_INFOTIP));
  1561. const CPLINK_DESC g_SLink_SystemRestore = {
  1562. &g_SLinkRes_SystemRestore_Icon,
  1563. &g_SLinkRes_SystemRestore_Title,
  1564. &g_SLinkRes_SystemRestore_Infotip,
  1565. &g_LinkAction_SystemRestore
  1566. };
  1567. const CResSrcStatic g_SLinkRes_SwToCategoryView_Icon(MAKEINTRESOURCEW(IDI_CPLFLD));
  1568. const CResSrcStatic g_SLinkRes_SwToCategoryView_Title(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCATEGORYVIEW_TITLE));
  1569. const CResSrcStatic g_SLinkRes_SwToCategoryView_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCATEGORYVIEW_INFOTIP));
  1570. const CPLINK_DESC g_SLink_SwToCategoryView = {
  1571. &g_SLinkRes_SwToCategoryView_Icon,
  1572. &g_SLinkRes_SwToCategoryView_Title,
  1573. &g_SLinkRes_SwToCategoryView_Infotip,
  1574. &g_LinkAction_SwToCategoryView
  1575. };
  1576. const CResSrcStatic g_SLinkRes_SwToClassicView_Icon(MAKEINTRESOURCEW(IDI_CPLFLD));
  1577. const CResSrcStatic g_SLinkRes_SwToClassicView_Title(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCLASSICVIEW_TITLE));
  1578. const CResSrcStatic g_SLinkRes_SwToClassicView_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCLASSICVIEW_INFOTIP));
  1579. const CPLINK_DESC g_SLink_SwToClassicView = {
  1580. &g_SLinkRes_SwToClassicView_Icon,
  1581. &g_SLinkRes_SwToClassicView_Title,
  1582. &g_SLinkRes_SwToClassicView_Infotip,
  1583. &g_LinkAction_SwToClassicView
  1584. };
  1585. const CResSrcStatic g_SLinkRes_TsDisplay_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1586. const CResSrcStatic g_SLinkRes_TsDisplay_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSDISPLAY_TITLE));
  1587. const CResSrcStatic g_SLinkRes_TsDisplay_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSDISPLAY_INFOTIP));
  1588. const CPLINK_DESC g_SLink_TsDisplay = {
  1589. &g_SLinkRes_TsDisplay_Icon,
  1590. &g_SLinkRes_TsDisplay_Title,
  1591. &g_SLinkRes_TsDisplay_Infotip,
  1592. &g_LinkAction_TsDisplay
  1593. };
  1594. const CResSrcStatic g_SLinkRes_TsDvd_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1595. const CResSrcStatic g_SLinkRes_TsDvd_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSDVD_TITLE));
  1596. const CResSrcStatic g_SLinkRes_TsDvd_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSDVD_INFOTIP));
  1597. const CPLINK_DESC g_SLink_TsDvd = {
  1598. &g_SLinkRes_TsDvd_Icon,
  1599. &g_SLinkRes_TsDvd_Title,
  1600. &g_SLinkRes_TsDvd_Infotip,
  1601. &g_LinkAction_TsDvd
  1602. };
  1603. const CResSrcStatic g_SLinkRes_TsHardware_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1604. const CResSrcStatic g_SLinkRes_TsHardware_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSHARDWARE_TITLE));
  1605. const CResSrcStatic g_SLinkRes_TsHardware_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSHARDWARE_INFOTIP));
  1606. const CPLINK_DESC g_SLink_TsHardware = {
  1607. &g_SLinkRes_TsHardware_Icon,
  1608. &g_SLinkRes_TsHardware_Title,
  1609. &g_SLinkRes_TsHardware_Infotip,
  1610. &g_LinkAction_TsHardware
  1611. };
  1612. const CResSrcStatic g_SLinkRes_TsInetExplorer_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1613. const CResSrcStatic g_SLinkRes_TsInetExplorer_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSINETEXPLORER_TITLE));
  1614. const CResSrcStatic g_SLinkRes_TsInetExplorer_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSINETEXPLORER_INFOTIP));
  1615. const CPLINK_DESC g_SLink_TsInetExplorer = {
  1616. &g_SLinkRes_TsInetExplorer_Icon,
  1617. &g_SLinkRes_TsInetExplorer_Title,
  1618. &g_SLinkRes_TsInetExplorer_Infotip,
  1619. &g_LinkAction_TsInetExplorer
  1620. };
  1621. const CResSrcStatic g_SLinkRes_TsModem_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1622. const CResSrcStatic g_SLinkRes_TsModem_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSMODEM_TITLE));
  1623. const CResSrcStatic g_SLinkRes_TsModem_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSMODEM_INFOTIP));
  1624. const CPLINK_DESC g_SLink_TsModem = {
  1625. &g_SLinkRes_TsModem_Icon,
  1626. &g_SLinkRes_TsModem_Title,
  1627. &g_SLinkRes_TsModem_Infotip,
  1628. &g_LinkAction_TsModem
  1629. };
  1630. const CResSrcStatic g_SLinkRes_TsNetDiags_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1631. const CResSrcStatic g_SLinkRes_TsNetDiags_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSNETDIAGS_TITLE));
  1632. const CResSrcStatic g_SLinkRes_TsNetDiags_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSNETDIAGS_INFOTIP));
  1633. const CPLINK_DESC g_SLink_TsNetDiags = {
  1634. &g_SLinkRes_TsNetDiags_Icon,
  1635. &g_SLinkRes_TsNetDiags_Title,
  1636. &g_SLinkRes_TsNetDiags_Infotip,
  1637. &g_LinkAction_TsNetDiags
  1638. };
  1639. const CResSrcStatic g_SLinkRes_TsNetwork_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1640. const CResSrcFunc g_SLinkRes_TsNetwork_Title(GetTsNetworkTitle);
  1641. const CResSrcStatic g_SLinkRes_TsNetwork_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSNETWORK_INFOTIP));
  1642. const CPLINK_DESC g_SLink_TsNetwork = {
  1643. &g_SLinkRes_TsNetwork_Icon,
  1644. &g_SLinkRes_TsNetwork_Title,
  1645. &g_SLinkRes_TsNetwork_Infotip,
  1646. &g_LinkAction_TsNetwork
  1647. };
  1648. const CResSrcStatic g_SLinkRes_TsPrinting_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1649. const CResSrcStatic g_SLinkRes_TsPrinting_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSPRINTING_TITLE));
  1650. const CResSrcStatic g_SLinkRes_TsPrinting_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSPRINTING_INFOTIP));
  1651. const CPLINK_DESC g_SLink_TsPrinting = {
  1652. &g_SLinkRes_TsPrinting_Icon,
  1653. &g_SLinkRes_TsPrinting_Title,
  1654. &g_SLinkRes_TsPrinting_Infotip,
  1655. &g_LinkAction_TsPrinting
  1656. };
  1657. const CResSrcStatic g_SLinkRes_TsSharing_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1658. const CResSrcStatic g_SLinkRes_TsSharing_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSFILESHARING_TITLE));
  1659. const CResSrcStatic g_SLinkRes_TsSharing_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSFILESHARING_INFOTIP));
  1660. const CPLINK_DESC g_SLink_TsSharing = {
  1661. &g_SLinkRes_TsSharing_Icon,
  1662. &g_SLinkRes_TsSharing_Title,
  1663. &g_SLinkRes_TsSharing_Infotip,
  1664. &g_LinkAction_TsSharing
  1665. };
  1666. const CResSrcStatic g_SLinkRes_TsSound_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1667. const CResSrcStatic g_SLinkRes_TsSound_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSSOUND_TITLE));
  1668. const CResSrcStatic g_SLinkRes_TsSound_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSSOUND_INFOTIP));
  1669. const CPLINK_DESC g_SLink_TsSound = {
  1670. &g_SLinkRes_TsSound_Icon,
  1671. &g_SLinkRes_TsSound_Title,
  1672. &g_SLinkRes_TsSound_Infotip,
  1673. &g_LinkAction_TsSound
  1674. };
  1675. const CResSrcStatic g_SLinkRes_TsStartup_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER));
  1676. const CResSrcStatic g_SLinkRes_TsStartup_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSSTARTUP_TITLE));
  1677. const CResSrcStatic g_SLinkRes_TsStartup_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSSTARTUP_INFOTIP));
  1678. const CPLINK_DESC g_SLink_TsStartup = {
  1679. &g_SLinkRes_TsStartup_Icon,
  1680. &g_SLinkRes_TsStartup_Title,
  1681. &g_SLinkRes_TsStartup_Infotip,
  1682. &g_LinkAction_TsStartup
  1683. };
  1684. const CResSrcStatic g_TLinkRes_ViewPrinters_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1685. const CResSrcStatic g_TLinkRes_ViewPrinters_Title(MAKEINTRESOURCEW(IDS_CPTASK_VIEWPRINTERS_TITLE));
  1686. const CResSrcStatic g_TLinkRes_ViewPrinters_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_VIEWPRINTERS_INFOTIP));
  1687. const CPLINK_DESC g_TLink_ViewPrinters = {
  1688. &g_TLinkRes_ViewPrinters_Icon,
  1689. &g_TLinkRes_ViewPrinters_Title,
  1690. &g_TLinkRes_ViewPrinters_Infotip,
  1691. &g_LinkAction_ViewPrinters
  1692. };
  1693. const CResSrcStatic g_TLinkRes_VisualPerf_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1694. const CResSrcStatic g_TLinkRes_VisualPerf_Title(MAKEINTRESOURCEW(IDS_CPTASK_VISUALPERF_TITLE));
  1695. const CResSrcStatic g_TLinkRes_VisualPerf_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_VISUALPERF_INFOTIP));
  1696. const CPLINK_DESC g_TLink_VisualPerf = {
  1697. &g_TLinkRes_VisualPerf_Icon,
  1698. &g_TLinkRes_VisualPerf_Title,
  1699. &g_TLinkRes_VisualPerf_Infotip,
  1700. &g_LinkAction_VisualPerf
  1701. };
  1702. const CResSrcStatic g_TLinkRes_VpnConnections_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1703. const CResSrcStatic g_TLinkRes_VpnConnections_Title(MAKEINTRESOURCEW(IDS_CPTASK_VPNCONNECTION_TITLE));
  1704. const CResSrcStatic g_TLinkRes_VpnConnections_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_VPNCONNECTION_INFOTIP));
  1705. const CPLINK_DESC g_TLink_VpnConnections = {
  1706. &g_TLinkRes_VpnConnections_Icon,
  1707. &g_TLinkRes_VpnConnections_Title,
  1708. &g_TLinkRes_VpnConnections_Infotip,
  1709. &g_LinkAction_VpnConnections
  1710. };
  1711. const CResSrcStatic g_TLinkRes_Wallpaper_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK));
  1712. const CResSrcStatic g_TLinkRes_Wallpaper_Title(MAKEINTRESOURCEW(IDS_CPTASK_WALLPAPER_TITLE));
  1713. const CResSrcStatic g_TLinkRes_Wallpaper_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_WALLPAPER_INFOTIP));
  1714. const CPLINK_DESC g_TLink_Wallpaper = {
  1715. &g_TLinkRes_Wallpaper_Icon,
  1716. &g_TLinkRes_Wallpaper_Title,
  1717. &g_TLinkRes_Wallpaper_Infotip,
  1718. &g_LinkAction_Wallpaper
  1719. };
  1720. const CResSrcStatic g_SLinkRes_WindowsUpdate_Icon(MAKEINTRESOURCEW(IDI_WINUPDATE));
  1721. const CResSrcStatic g_SLinkRes_WindowsUpdate_Title(MAKEINTRESOURCEW(IDS_CPTASK_WINDOWSUPDATE_TITLE));
  1722. const CResSrcStatic g_SLinkRes_WindowsUpdate_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_WINDOWSUPDATE_INFOTIP));
  1723. const CPLINK_DESC g_SLink_WindowsUpdate = {
  1724. &g_SLinkRes_WindowsUpdate_Icon,
  1725. &g_SLinkRes_WindowsUpdate_Title,
  1726. &g_SLinkRes_WindowsUpdate_Infotip,
  1727. &g_LinkAction_WindowsUpdate
  1728. };
  1729. //-----------------------------------------------------------------------------
  1730. // View page definitions.
  1731. //-----------------------------------------------------------------------------
  1732. //
  1733. // Main Control Panel page.
  1734. //
  1735. const CPLINK_DESC *g_rgpLink_Cpl_SeeAlso[] = {
  1736. &g_SLink_WindowsUpdate,
  1737. &g_SLink_HelpAndSupport,
  1738. &g_SLink_32CtrlPanel,
  1739. &g_SLink_OtherCplOptions,
  1740. NULL
  1741. };
  1742. const CPLINK_DESC *g_rgpLink_Cpl_SwToClassicView[] = {
  1743. &g_SLink_SwToClassicView,
  1744. NULL
  1745. };
  1746. const CPLINK_DESC *g_rgpLink_Cpl_SwToCategoryView[] = {
  1747. &g_SLink_SwToCategoryView,
  1748. NULL
  1749. };
  1750. //
  1751. // Accounts category
  1752. //
  1753. const CPLINK_DESC *g_rgpLink_Accounts_Tasks[] = {
  1754. &g_TLink_AccountsChange,
  1755. &g_TLink_AccountsCreate, // Active on non-server SKU
  1756. &g_TLink_AccountsCreate2, // Active on server SKU
  1757. &g_TLink_AccountsPict,
  1758. NULL
  1759. };
  1760. const CPLINK_DESC *g_rgpLink_Accounts_SeeAlso[] = {
  1761. &g_TLink_CatAppearance,
  1762. NULL
  1763. };
  1764. const CPLINK_DESC *g_rgpLink_Accounts_LearnAbout[] = {
  1765. &g_SLink_LearnAccounts,
  1766. &g_SLink_LearnAccountsTypes,
  1767. &g_SLink_LearnAccountsChangeName,
  1768. &g_SLink_LearnAccountsCreate,
  1769. &g_SLink_LearnSwitchUsers,
  1770. NULL
  1771. };
  1772. const CPCAT_DESC g_Category_Accounts = {
  1773. eCPCAT_ACCOUNTS,
  1774. L"Security_and_User_Accounts",
  1775. &g_TLink_CatAccounts,
  1776. g_rgpLink_Accounts_Tasks,
  1777. { g_rgpLink_Accounts_SeeAlso, NULL, g_rgpLink_Accounts_LearnAbout }
  1778. };
  1779. //
  1780. // Accessibility category
  1781. //
  1782. const CPLINK_DESC *g_rgpLink_Accessibility_Tasks[] = {
  1783. &g_TLink_HighContrast,
  1784. &g_TLink_AccessWizard,
  1785. NULL
  1786. };
  1787. const CPLINK_DESC *g_rgpLink_Accessibility_SeeAlso[] = {
  1788. &g_SLink_Magnifier,
  1789. &g_SLink_OnScreenKbd,
  1790. NULL
  1791. };
  1792. const CPCAT_DESC g_Category_Accessibility = {
  1793. eCPCAT_ACCESSIBILITY,
  1794. L"Accessibility",
  1795. &g_TLink_CatAccessibility,
  1796. g_rgpLink_Accessibility_Tasks,
  1797. { g_rgpLink_Accessibility_SeeAlso, NULL, NULL },
  1798. };
  1799. //
  1800. // Appearance category
  1801. //
  1802. const CPLINK_DESC *g_rgpLink_Appearance_Tasks[] = {
  1803. &g_TLink_DisplayTheme,
  1804. &g_TLink_Wallpaper,
  1805. &g_TLink_ScreenSaver,
  1806. &g_TLink_DisplayRes,
  1807. NULL
  1808. };
  1809. const CPLINK_DESC *g_rgpLink_Appearance_SeeAlso[] = {
  1810. &g_SLink_FontsFolder,
  1811. &g_SLink_MousePointers,
  1812. &g_SLink_HighContrast,
  1813. &g_SLink_AccountsPict,
  1814. NULL
  1815. };
  1816. const CPLINK_DESC *g_rgpLink_Appearance_Troubleshoot[] = {
  1817. &g_SLink_TsDisplay,
  1818. &g_SLink_TsSound,
  1819. NULL
  1820. };
  1821. const CPCAT_DESC g_Category_Appearance = {
  1822. eCPCAT_APPEARANCE,
  1823. L"Appearance_and_Themes",
  1824. &g_TLink_CatAppearance,
  1825. g_rgpLink_Appearance_Tasks,
  1826. { g_rgpLink_Appearance_SeeAlso, g_rgpLink_Appearance_Troubleshoot, NULL }
  1827. };
  1828. //
  1829. // Add/Remove Programs (aka ARP) category
  1830. //
  1831. const CPLINK_DESC *g_rgpLink_Arp_SeeAlso[] = {
  1832. &g_SLink_WindowsUpdate,
  1833. &g_SLink_AutoUpdate,
  1834. NULL
  1835. };
  1836. const CPLINK_DESC *g_rgpLink_Arp_Tasks[] = {
  1837. &g_TLink_AddProgram,
  1838. &g_TLink_RemoveProgram,
  1839. NULL
  1840. };
  1841. const CPCAT_DESC g_Category_Arp = {
  1842. eCPCAT_ARP,
  1843. L"Add_or_Remove_Programs",
  1844. &g_TLink_CatArp,
  1845. g_rgpLink_Arp_Tasks,
  1846. { g_rgpLink_Arp_SeeAlso, NULL, NULL },
  1847. };
  1848. //
  1849. // Hardware category
  1850. //
  1851. const CPLINK_DESC *g_rgpLink_Hardware_Tasks[] = {
  1852. &g_TLink_ViewPrinters,
  1853. &g_TLink_AddPrinter,
  1854. NULL
  1855. };
  1856. const CPLINK_DESC *g_rgpLink_Hardware_SeeAlso[] = {
  1857. &g_SLink_HardwareWizard,
  1858. &g_SLink_DisplayCpl,
  1859. &g_SLink_Sounds,
  1860. &g_SLink_PowerCpl,
  1861. &g_SLink_SystemCpl,
  1862. NULL
  1863. };
  1864. const CPLINK_DESC *g_rgpLink_Hardware_Troubleshoot[] = {
  1865. &g_SLink_TsHardware,
  1866. &g_SLink_TsPrinting,
  1867. &g_SLink_TsNetwork,
  1868. NULL
  1869. };
  1870. const CPCAT_DESC g_Category_Hardware = {
  1871. eCPCAT_HARDWARE,
  1872. L"Printers_and_Other_Hardware",
  1873. &g_TLink_CatHardware,
  1874. g_rgpLink_Hardware_Tasks,
  1875. { g_rgpLink_Hardware_SeeAlso, g_rgpLink_Hardware_Troubleshoot, NULL }
  1876. };
  1877. //
  1878. // Network category
  1879. //
  1880. const CPLINK_DESC *g_rgpLink_Network_Tasks[] = {
  1881. &g_TLink_NetConnections,
  1882. &g_TLink_VpnConnections,
  1883. &g_TLink_HomeNetWizard,
  1884. NULL
  1885. };
  1886. const CPLINK_DESC *g_rgpLink_Network_SeeAlso[] = {
  1887. &g_SLink_MyNetPlaces,
  1888. &g_SLink_Hardware,
  1889. &g_SLink_RemoteDesktop,
  1890. &g_SLink_PhoneModemCpl,
  1891. NULL
  1892. };
  1893. const CPLINK_DESC *g_rgpLink_Network_Troubleshoot[] = {
  1894. &g_SLink_TsNetwork, // Pro/Personal only.
  1895. &g_SLink_TsInetExplorer, // Pro/Personal only.
  1896. &g_SLink_TsSharing, // Server only.
  1897. &g_SLink_TsModem, // Server only.
  1898. &g_SLink_TsNetDiags, // All SKUs.
  1899. NULL
  1900. };
  1901. const CPCAT_DESC g_Category_Network = {
  1902. eCPCAT_NETWORK,
  1903. L"Network_Connections",
  1904. &g_TLink_CatNetwork,
  1905. g_rgpLink_Network_Tasks,
  1906. { g_rgpLink_Network_SeeAlso, g_rgpLink_Network_Troubleshoot, NULL }
  1907. };
  1908. //
  1909. // Other CPLs category
  1910. //
  1911. const CPLINK_DESC *g_rgpLink_Other_SeeAlso[] = {
  1912. &g_SLink_WindowsUpdate,
  1913. &g_SLink_HelpAndSupport,
  1914. NULL
  1915. };
  1916. const CPCAT_DESC g_Category_Other = {
  1917. eCPCAT_OTHER,
  1918. NULL, // "Other" uses std Control Panel help topic.
  1919. &g_TLink_CatOther,
  1920. NULL,
  1921. { g_rgpLink_Other_SeeAlso, NULL, NULL }
  1922. };
  1923. //
  1924. // PerfMaint category
  1925. //
  1926. const CPLINK_DESC *g_rgpLink_PerfMaint_Tasks[] = {
  1927. &g_TLink_SystemCpl,
  1928. &g_TLink_VisualPerf,
  1929. &g_TLink_CleanUpDisk,
  1930. &g_TLink_BackupData,
  1931. &g_TLink_Defrag,
  1932. NULL
  1933. };
  1934. const CPLINK_DESC *g_rgpLink_PerfMaint_SeeAlso[] = {
  1935. &g_SLink_FileTypes,
  1936. &g_SLink_SystemRestore,
  1937. NULL
  1938. };
  1939. const CPLINK_DESC *g_rgpLink_PerfMaint_Troubleshoot[] = {
  1940. &g_SLink_TsStartup,
  1941. NULL
  1942. };
  1943. const CPCAT_DESC g_Category_PerfMaint = {
  1944. eCPCAT_PERFMAINT,
  1945. L"Performance_and_Maintenance",
  1946. &g_TLink_CatPerfMaint,
  1947. g_rgpLink_PerfMaint_Tasks,
  1948. { g_rgpLink_PerfMaint_SeeAlso, g_rgpLink_PerfMaint_Troubleshoot, NULL },
  1949. };
  1950. //
  1951. // Regional category
  1952. //
  1953. const CPLINK_DESC *g_rgpLink_Regional_Tasks[] = {
  1954. &g_TLink_DateTime,
  1955. &g_TLink_Region,
  1956. &g_TLink_Language,
  1957. NULL
  1958. };
  1959. const CPLINK_DESC *g_rgpLink_Regional_SeeAlso[] = {
  1960. &g_SLink_ScheduledTasks,
  1961. NULL
  1962. };
  1963. const CPCAT_DESC g_Category_Regional = {
  1964. eCPCAT_REGIONAL,
  1965. L"Date__Time__Language_and_Regional_Settings",
  1966. &g_TLink_CatRegional,
  1967. g_rgpLink_Regional_Tasks,
  1968. { g_rgpLink_Regional_SeeAlso, NULL, NULL },
  1969. };
  1970. //
  1971. // Sound category
  1972. //
  1973. const CPLINK_DESC *g_rgpLink_Sound_Tasks[] = {
  1974. &g_TLink_SoundVolume,
  1975. &g_TLink_SoundSchemes,
  1976. &g_TLink_SpeakerSettings,
  1977. NULL
  1978. };
  1979. const CPLINK_DESC *g_rgpLink_Sound_SeeAlso[] = {
  1980. &g_SLink_SoundAccessibility,
  1981. &g_SLink_SoundVolumeAdv,
  1982. NULL
  1983. };
  1984. const CPLINK_DESC *g_rgpLink_Sound_Troubleshoot[] = {
  1985. &g_SLink_TsSound,
  1986. &g_SLink_TsDvd,
  1987. NULL
  1988. };
  1989. const CPCAT_DESC g_Category_Sound = {
  1990. eCPCAT_SOUND,
  1991. L"Sounds__Speech_and_Audio_Devices",
  1992. &g_TLink_CatSound,
  1993. g_rgpLink_Sound_Tasks,
  1994. { g_rgpLink_Sound_SeeAlso, g_rgpLink_Sound_Troubleshoot, NULL }
  1995. };
  1996. //
  1997. // ********* IMPORTANT **********
  1998. //
  1999. // The order of these entries MUST match up with the category ID
  2000. // values in the cCPCAT enumeration. These IDs also map directly
  2001. // to the SCID_CONTROLPANELCATEGORY value stored for each CPL
  2002. // applet in the registry.
  2003. //
  2004. // Code using a category ID will map directly to this array.
  2005. // Order of display in the Category selection view is handled
  2006. // by the function CCplView::_DisplayIndexToCategoryIndex in
  2007. // cpview.cpp.
  2008. //
  2009. const CPCAT_DESC *g_rgpCplCatInfo[] = {
  2010. &g_Category_Other,
  2011. &g_Category_Appearance,
  2012. &g_Category_Hardware,
  2013. &g_Category_Network,
  2014. &g_Category_Sound,
  2015. &g_Category_PerfMaint,
  2016. &g_Category_Regional,
  2017. &g_Category_Accessibility,
  2018. &g_Category_Arp,
  2019. &g_Category_Accounts,
  2020. NULL,
  2021. };
  2022. //-----------------------------------------------------------------------------
  2023. // Helper functions used in support of the namespace.
  2024. //-----------------------------------------------------------------------------
  2025. //
  2026. // Copy one DPA of IUICommand ptrs to another.
  2027. // Returns:
  2028. // S_OK - All items copied.
  2029. // Error - Something failed.
  2030. //
  2031. HRESULT
  2032. CplNamespace_CopyCommandArray(
  2033. const CDpaUiCommand& rgFrom,
  2034. CDpaUiCommand *prgTo
  2035. )
  2036. {
  2037. ASSERT(NULL != prgTo);
  2038. ASSERT(0 == prgTo->Count());
  2039. HRESULT hr = S_OK;
  2040. const int cCommands = rgFrom.Count();
  2041. for (int i = 0; i < cCommands && SUCCEEDED(hr); i++)
  2042. {
  2043. IUICommand *pc = const_cast<IUICommand *>(rgFrom.Get(i));
  2044. ASSERT(NULL != pc);
  2045. if (-1 != prgTo->Append(pc))
  2046. {
  2047. pc->AddRef();
  2048. }
  2049. else
  2050. {
  2051. hr = E_OUTOFMEMORY;
  2052. }
  2053. }
  2054. return THR(hr);
  2055. }
  2056. //
  2057. // Create a new IUICommand object from a CPLINK_DESC structure.
  2058. //
  2059. HRESULT
  2060. CplNamespace_CreateUiCommand(
  2061. IUnknown *punkSite,
  2062. const CPLINK_DESC& ld,
  2063. IUICommand **ppc
  2064. )
  2065. {
  2066. ASSERT(NULL != ppc);
  2067. ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
  2068. *ppc = NULL;
  2069. ICplNamespace *pns;
  2070. HRESULT hr = IUnknown_QueryService(punkSite, SID_SControlPanelView, IID_ICplNamespace, (void **)&pns);
  2071. if (SUCCEEDED(hr))
  2072. {
  2073. hr = CPL::Create_CplUiCommand(ld.prsrcName->GetResource(pns),
  2074. ld.prsrcInfotip->GetResource(pns),
  2075. ld.prsrcIcon->GetResource(pns),
  2076. ld.pAction,
  2077. IID_IUICommand,
  2078. (void **)ppc);
  2079. pns->Release();
  2080. }
  2081. return THR(hr);
  2082. }
  2083. //
  2084. // Create a new IUIElement object for a given webview type.
  2085. // The returned IUIElement object represents the header for
  2086. // the requested webview menu.
  2087. //
  2088. HRESULT
  2089. CplNamespace_CreateWebViewHeaderElement(
  2090. eCPWVTYPE eType,
  2091. IUIElement **ppele
  2092. )
  2093. {
  2094. ASSERT(0 <= eType && eCPWVTYPE_NUMTYPES > eType);
  2095. ASSERT(NULL != ppele);
  2096. ASSERT(!IsBadWritePtr(ppele, sizeof(*ppele)));
  2097. static const struct
  2098. {
  2099. LPCWSTR pszName;
  2100. LPCWSTR pszInfotip;
  2101. LPCWSTR pszIcon;
  2102. } rgHeaderInfo[] = {
  2103. //
  2104. // eCPWVTYPE_CPANEL
  2105. //
  2106. {
  2107. MAKEINTRESOURCEW(IDS_CONTROLPANEL),
  2108. MAKEINTRESOURCEW(IDS_CPTASK_CONTROLPANEL_INFOTIP),
  2109. MAKEINTRESOURCEW(IDI_CPLFLD)
  2110. },
  2111. //
  2112. // eCPWVTYPE_SEEALSO
  2113. //
  2114. {
  2115. MAKEINTRESOURCEW(IDS_CPTASK_SEEALSO_TITLE),
  2116. MAKEINTRESOURCEW(IDS_CPTASK_SEEALSO_INFOTIP),
  2117. MAKEINTRESOURCEW(IDI_CPTASK_SEEALSO)
  2118. },
  2119. //
  2120. // eCPWVTYPE_TROUBLESHOOTER
  2121. //
  2122. {
  2123. MAKEINTRESOURCEW(IDS_CPTASK_TROUBLESHOOTER_TITLE),
  2124. MAKEINTRESOURCEW(IDS_CPTASK_TROUBLESHOOTER_INFOTIP),
  2125. MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)
  2126. },
  2127. //
  2128. // eCPWVTYPE_LEARNABOUT
  2129. //
  2130. {
  2131. MAKEINTRESOURCEW(IDS_CPTASK_LEARNABOUT_TITLE),
  2132. MAKEINTRESOURCEW(IDS_CPTASK_LEARNABOUT_INFOTIP),
  2133. MAKEINTRESOURCEW(IDI_CPTASK_LEARNABOUT)
  2134. }
  2135. };
  2136. *ppele = NULL;
  2137. HRESULT hr = Create_CplUiElement(rgHeaderInfo[eType].pszName,
  2138. rgHeaderInfo[eType].pszInfotip,
  2139. rgHeaderInfo[eType].pszIcon,
  2140. IID_IUIElement,
  2141. (void **)ppele);
  2142. return THR(hr);
  2143. }
  2144. //-----------------------------------------------------------------------------
  2145. // UI Command Enumeration
  2146. //-----------------------------------------------------------------------------
  2147. class IEnumCommandBase
  2148. {
  2149. public:
  2150. virtual ~IEnumCommandBase() { }
  2151. virtual HRESULT Next(IUnknown *punkSite, IUICommand **ppc) = 0;
  2152. virtual HRESULT Skip(ULONG n) = 0;
  2153. virtual HRESULT Reset(void) = 0;
  2154. virtual HRESULT Clone(IEnumCommandBase **ppEnum) = 0;
  2155. };
  2156. //
  2157. // Used to enumerate UI Command objects that originate from static
  2158. // initialization information in the CPL namespace.
  2159. //
  2160. class CEnumCommand_LinkDesc : public IEnumCommandBase
  2161. {
  2162. public:
  2163. CEnumCommand_LinkDesc(const CPLINK_DESC **ppld);
  2164. ~CEnumCommand_LinkDesc(void);
  2165. HRESULT Next(IUnknown *punkSite, IUICommand **ppc);
  2166. HRESULT Skip(ULONG n);
  2167. HRESULT Reset(void);
  2168. HRESULT Clone(IEnumCommandBase **ppEnum);
  2169. private:
  2170. const CPLINK_DESC ** const m_ppldFirst; // First item in descriptor array.
  2171. const CPLINK_DESC **m_ppldCurrent; // 'Current' item referenced.
  2172. };
  2173. //
  2174. // Used to enumerate UI Command objects that already exist in
  2175. // a DPA of IUICommand pointers. In particular, this is used
  2176. // to enumerate the UICommand objects that represent CPL applets
  2177. // in the user interface.
  2178. //
  2179. class CEnumCommand_Array : public IEnumCommandBase
  2180. {
  2181. public:
  2182. CEnumCommand_Array(void);
  2183. ~CEnumCommand_Array(void);
  2184. HRESULT Next(IUnknown *punkSite, IUICommand **ppc);
  2185. HRESULT Skip(ULONG n);
  2186. HRESULT Reset(void);
  2187. HRESULT Clone(IEnumCommandBase **ppEnum);
  2188. HRESULT Initialize(const CDpaUiCommand& rgCommands);
  2189. private:
  2190. CDpaUiCommand m_rgCommands; // DPA of IUICommand ptrs.
  2191. int m_iCurrent; // 'Current' item in enumeration.
  2192. //
  2193. // Prevent copy.
  2194. //
  2195. CEnumCommand_Array(const CEnumCommand_Array& rhs); // not implemented.
  2196. CEnumCommand_Array& operator = (const CEnumCommand_Array& rhs); // not implemented.
  2197. };
  2198. //-----------------------------------------------------------------------------
  2199. // CEnumCommand_LinkDesc implementation.
  2200. //-----------------------------------------------------------------------------
  2201. CEnumCommand_LinkDesc::CEnumCommand_LinkDesc(
  2202. const CPLINK_DESC **ppld
  2203. ) : m_ppldFirst(ppld),
  2204. m_ppldCurrent(ppld)
  2205. {
  2206. TraceMsg(TF_LIFE, "CEnumCommand_LinkDesc::CEnumCommand_LinkDesc, this = 0x%x", this);
  2207. }
  2208. CEnumCommand_LinkDesc::~CEnumCommand_LinkDesc(
  2209. void
  2210. )
  2211. {
  2212. TraceMsg(TF_LIFE, "CEnumCommand_LinkDesc::~CEnumCommand_LinkDesc, this = 0x%x", this);
  2213. }
  2214. HRESULT
  2215. CEnumCommand_LinkDesc::Next(
  2216. IUnknown *punkSite,
  2217. IUICommand **ppc
  2218. )
  2219. {
  2220. ASSERT(NULL != ppc);
  2221. ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
  2222. HRESULT hr = S_FALSE;
  2223. if (NULL != m_ppldCurrent && NULL != *m_ppldCurrent)
  2224. {
  2225. hr = CplNamespace_CreateUiCommand(punkSite, **m_ppldCurrent, ppc);
  2226. m_ppldCurrent++;
  2227. }
  2228. return THR(hr);
  2229. }
  2230. HRESULT
  2231. CEnumCommand_LinkDesc::Reset(
  2232. void
  2233. )
  2234. {
  2235. m_ppldCurrent = m_ppldFirst;
  2236. return S_OK;
  2237. }
  2238. HRESULT
  2239. CEnumCommand_LinkDesc::Skip(
  2240. ULONG n
  2241. )
  2242. {
  2243. if (NULL != m_ppldCurrent)
  2244. {
  2245. while(0 < n-- && NULL != *m_ppldCurrent)
  2246. {
  2247. m_ppldCurrent++;
  2248. }
  2249. }
  2250. return 0 == n ? S_OK : S_FALSE;
  2251. }
  2252. HRESULT
  2253. CEnumCommand_LinkDesc::Clone(
  2254. IEnumCommandBase **ppenum
  2255. )
  2256. {
  2257. ASSERT(NULL != ppenum);
  2258. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  2259. HRESULT hr = E_OUTOFMEMORY;
  2260. *ppenum = new CEnumCommand_LinkDesc(m_ppldFirst);
  2261. if (NULL != *ppenum)
  2262. {
  2263. hr = S_OK;
  2264. }
  2265. return THR(hr);
  2266. }
  2267. //-----------------------------------------------------------------------------
  2268. // CEnumCommand_Array implementation.
  2269. //-----------------------------------------------------------------------------
  2270. CEnumCommand_Array::CEnumCommand_Array(
  2271. void
  2272. ) : m_iCurrent(0)
  2273. {
  2274. TraceMsg(TF_LIFE, "CEnumCommand_Array::CEnumCommand_Array, this = 0x%x", this);
  2275. }
  2276. CEnumCommand_Array::~CEnumCommand_Array(
  2277. void
  2278. )
  2279. {
  2280. TraceMsg(TF_LIFE, "CEnumCommand_Array::~CEnumCommand_Array, this = 0x%x", this);
  2281. }
  2282. HRESULT
  2283. CEnumCommand_Array::Initialize(
  2284. const CDpaUiCommand& rgCommands
  2285. )
  2286. {
  2287. ASSERT(0 == m_rgCommands.Count());
  2288. ASSERT(0 == m_iCurrent);
  2289. HRESULT hr = CplNamespace_CopyCommandArray(rgCommands, &m_rgCommands);
  2290. return THR(hr);
  2291. }
  2292. HRESULT
  2293. CEnumCommand_Array::Next(
  2294. IUnknown *punkSite,
  2295. IUICommand **ppc
  2296. )
  2297. {
  2298. ASSERT(NULL != ppc);
  2299. ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
  2300. UNREFERENCED_PARAMETER(punkSite);
  2301. HRESULT hr = S_FALSE;
  2302. if (m_iCurrent < m_rgCommands.Count())
  2303. {
  2304. *ppc = m_rgCommands.Get(m_iCurrent++);
  2305. ASSERT(NULL != *ppc);
  2306. (*ppc)->AddRef();
  2307. hr = S_OK;
  2308. }
  2309. return THR(hr);
  2310. }
  2311. HRESULT
  2312. CEnumCommand_Array::Reset(
  2313. void
  2314. )
  2315. {
  2316. m_iCurrent = 0;
  2317. return S_OK;
  2318. }
  2319. HRESULT
  2320. CEnumCommand_Array::Skip(
  2321. ULONG n
  2322. )
  2323. {
  2324. while(0 < n-- && m_iCurrent < m_rgCommands.Count())
  2325. {
  2326. m_iCurrent++;
  2327. }
  2328. return 0 == n ? S_OK : S_FALSE;
  2329. }
  2330. HRESULT
  2331. CEnumCommand_Array::Clone(
  2332. IEnumCommandBase **ppenum
  2333. )
  2334. {
  2335. ASSERT(NULL != ppenum);
  2336. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  2337. HRESULT hr = E_OUTOFMEMORY;
  2338. *ppenum = new CEnumCommand_Array();
  2339. if (NULL != *ppenum)
  2340. {
  2341. hr = static_cast<CEnumCommand_Array *>(*ppenum)->Initialize(m_rgCommands);
  2342. if (FAILED(hr))
  2343. {
  2344. delete *ppenum;
  2345. *ppenum = NULL;
  2346. }
  2347. }
  2348. return THR(hr);
  2349. }
  2350. //-----------------------------------------------------------------------------
  2351. // CEnumCommand
  2352. //-----------------------------------------------------------------------------
  2353. //
  2354. // Enumerates IUICommand pointers for UICommand objects in the
  2355. // Control Panel namespace.
  2356. //
  2357. class CEnumCommand : public CObjectWithSite,
  2358. public IEnumUICommand
  2359. {
  2360. public:
  2361. ~CEnumCommand(void);
  2362. //
  2363. // IUnknown
  2364. //
  2365. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  2366. STDMETHOD_(ULONG, AddRef)(void);
  2367. STDMETHOD_(ULONG, Release)(void);
  2368. //
  2369. // IEnumUICommand
  2370. //
  2371. STDMETHOD(Next)(ULONG celt, IUICommand **pUICommand, ULONG *pceltFetched);
  2372. STDMETHOD(Skip)(ULONG celt);
  2373. STDMETHOD(Reset)(void);
  2374. STDMETHOD(Clone)(IEnumUICommand **ppenum);
  2375. static HRESULT CreateInstance(IUnknown *punkSite, const CPLINK_DESC **ppld, REFIID riid, void **ppvEnum);
  2376. static HRESULT CreateInstance(IUnknown *punkSite, const CDpaUiCommand& rgCommands, REFIID riid, void **ppvEnum);
  2377. private:
  2378. LONG m_cRef;
  2379. IEnumCommandBase *m_pImpl; // Ptr to actual implementation.
  2380. CEnumCommand(void);
  2381. //
  2382. // Prevent copy.
  2383. //
  2384. CEnumCommand(const CEnumCommand& rhs); // not implemented.
  2385. CEnumCommand& operator = (const CEnumCommand& rhs); // not implemented.
  2386. bool _IsRestricted(IUICommand *puic);
  2387. };
  2388. CEnumCommand::CEnumCommand(
  2389. void
  2390. ) : m_cRef(1),
  2391. m_pImpl(NULL)
  2392. {
  2393. TraceMsg(TF_LIFE, "CEnumCommand::CEnumCommand, this = 0x%x", this);
  2394. }
  2395. CEnumCommand::~CEnumCommand(
  2396. void
  2397. )
  2398. {
  2399. TraceMsg(TF_LIFE, "CEnumCommand::~CEnumCommand, this = 0x%x", this);
  2400. delete m_pImpl;
  2401. }
  2402. //
  2403. // Creates a command enumerator from an array of link descriptions
  2404. // in the CPL namespace.
  2405. //
  2406. HRESULT
  2407. CEnumCommand::CreateInstance(
  2408. IUnknown *punkSite,
  2409. const CPLINK_DESC **ppld,
  2410. REFIID riid,
  2411. void **ppvOut
  2412. )
  2413. {
  2414. //
  2415. // Note that ppld can be NULL. It simply results in an
  2416. // empty enumerator.
  2417. //
  2418. ASSERT(NULL != punkSite);
  2419. ASSERT(NULL != ppvOut);
  2420. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  2421. *ppvOut = NULL;
  2422. HRESULT hr = E_OUTOFMEMORY;
  2423. CEnumCommand *pec = new CEnumCommand();
  2424. if (NULL != pec)
  2425. {
  2426. pec->m_pImpl = new CEnumCommand_LinkDesc(ppld);
  2427. if (NULL != pec->m_pImpl)
  2428. {
  2429. hr = pec->QueryInterface(riid, ppvOut);
  2430. if (SUCCEEDED(hr))
  2431. {
  2432. hr = IUnknown_SetSite(static_cast<IUnknown *>(*ppvOut), punkSite);
  2433. }
  2434. }
  2435. pec->Release();
  2436. }
  2437. return THR(hr);
  2438. }
  2439. //
  2440. // Creates a command enumerator from a DPA of IUICommand ptrs.
  2441. //
  2442. HRESULT
  2443. CEnumCommand::CreateInstance(
  2444. IUnknown *punkSite,
  2445. const CDpaUiCommand& rgCommands,
  2446. REFIID riid,
  2447. void **ppvOut
  2448. )
  2449. {
  2450. ASSERT(NULL != punkSite);
  2451. ASSERT(NULL != ppvOut);
  2452. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  2453. *ppvOut = NULL;
  2454. HRESULT hr = E_OUTOFMEMORY;
  2455. CEnumCommand *pec = new CEnumCommand();
  2456. if (NULL != pec)
  2457. {
  2458. pec->m_pImpl = new CEnumCommand_Array();
  2459. if (NULL != pec->m_pImpl)
  2460. {
  2461. hr = static_cast<CEnumCommand_Array *>(pec->m_pImpl)->Initialize(rgCommands);
  2462. if (SUCCEEDED(hr))
  2463. {
  2464. hr = pec->QueryInterface(riid, ppvOut);
  2465. if (SUCCEEDED(hr))
  2466. {
  2467. hr = IUnknown_SetSite(static_cast<IUnknown *>(*ppvOut), punkSite);
  2468. }
  2469. }
  2470. }
  2471. pec->Release();
  2472. }
  2473. return THR(hr);
  2474. }
  2475. STDMETHODIMP
  2476. CEnumCommand::QueryInterface(
  2477. REFIID riid,
  2478. void **ppv
  2479. )
  2480. {
  2481. ASSERT(NULL != ppv);
  2482. ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
  2483. static const QITAB qit[] = {
  2484. QITABENT(CEnumCommand, IEnumUICommand),
  2485. QITABENT(CEnumCommand, IObjectWithSite),
  2486. { 0 },
  2487. };
  2488. HRESULT hr = QISearch(this, qit, riid, ppv);
  2489. return E_NOINTERFACE == hr ? hr : THR(hr);
  2490. }
  2491. STDMETHODIMP_(ULONG)
  2492. CEnumCommand::AddRef(
  2493. void
  2494. )
  2495. {
  2496. return InterlockedIncrement(&m_cRef);
  2497. }
  2498. STDMETHODIMP_(ULONG)
  2499. CEnumCommand::Release(
  2500. void
  2501. )
  2502. {
  2503. if (InterlockedDecrement(&m_cRef))
  2504. return m_cRef;
  2505. delete this;
  2506. return 0;
  2507. }
  2508. STDMETHODIMP
  2509. CEnumCommand::Next(
  2510. ULONG celt,
  2511. IUICommand **ppUICommand,
  2512. ULONG *pceltFetched
  2513. )
  2514. {
  2515. ASSERT(NULL != ppUICommand);
  2516. ASSERT(!IsBadWritePtr(ppUICommand, sizeof(*ppUICommand) * celt));
  2517. ASSERT(NULL != m_pImpl);
  2518. HRESULT hr = S_OK;
  2519. ULONG celtFetched = 0;
  2520. while(S_OK == hr && 0 < celt)
  2521. {
  2522. ASSERT(NULL != CObjectWithSite::_punkSite);
  2523. IUICommand *puic;
  2524. //
  2525. // This is a little weird. I pass the site ptr to the
  2526. // Next() method but then also set the returned object's
  2527. // site when it's returned by Next(). Why not just set
  2528. // the site in the Next() implementation? Next() needs the site
  2529. // ptr to pass through to any IResSrc::GetResource implementation
  2530. // when retrieving the resources for any given UI command object.
  2531. // This is because the resource used can vary depending upon state
  2532. // information stored in the namespace. However, to simplify
  2533. // lifetime management, I want to 'set' the site on the returned
  2534. // objects in only one place; this place. That way, the derived
  2535. // enumerator instance attached to m_pImpl doesn't need to worry
  2536. // about setting the site. We do it in one place for all
  2537. // implementations. [brianau - 3/16/01]
  2538. //
  2539. hr = m_pImpl->Next(CObjectWithSite::_punkSite, &puic);
  2540. if (S_OK == hr)
  2541. {
  2542. //
  2543. // It's important that we set the object's 'site' before
  2544. // checking the restriction. The restriction checking
  2545. // code requires access to the CplNamespace which is obtained
  2546. // through the site.
  2547. //
  2548. hr = IUnknown_SetSite(puic, CObjectWithSite::_punkSite);
  2549. if (SUCCEEDED(hr))
  2550. {
  2551. if (!_IsRestricted(puic))
  2552. {
  2553. celt--;
  2554. celtFetched++;
  2555. (*ppUICommand++ = puic)->AddRef();
  2556. }
  2557. }
  2558. puic->Release();
  2559. }
  2560. }
  2561. if (NULL != pceltFetched)
  2562. {
  2563. *pceltFetched = celtFetched;
  2564. }
  2565. return THR(hr);
  2566. }
  2567. STDMETHODIMP
  2568. CEnumCommand::Skip(
  2569. ULONG celt
  2570. )
  2571. {
  2572. ASSERT(NULL != m_pImpl);
  2573. HRESULT hr = m_pImpl->Skip(celt);
  2574. return THR(hr);
  2575. }
  2576. STDMETHODIMP
  2577. CEnumCommand::Reset(
  2578. void
  2579. )
  2580. {
  2581. ASSERT(NULL != m_pImpl);
  2582. HRESULT hr = m_pImpl->Reset();
  2583. return THR(hr);
  2584. }
  2585. STDMETHODIMP
  2586. CEnumCommand::Clone(
  2587. IEnumUICommand **ppenum
  2588. )
  2589. {
  2590. ASSERT(NULL != ppenum);
  2591. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  2592. ASSERT(NULL != m_pImpl);
  2593. *ppenum = NULL;
  2594. HRESULT hr = E_OUTOFMEMORY;
  2595. CEnumCommand *pe = new CEnumCommand();
  2596. if (NULL != pe)
  2597. {
  2598. hr = m_pImpl->Clone(&(pe->m_pImpl));
  2599. if (SUCCEEDED(hr))
  2600. {
  2601. hr = pe->QueryInterface(IID_IEnumUICommand, (void **)ppenum);
  2602. }
  2603. pe->Release();
  2604. }
  2605. return THR(hr);
  2606. }
  2607. bool
  2608. CEnumCommand::_IsRestricted(
  2609. IUICommand *puic
  2610. )
  2611. {
  2612. ASSERT(NULL != puic);
  2613. bool bRestricted = false;
  2614. UISTATE uis;
  2615. HRESULT hr = puic->get_State(NULL, TRUE, &uis);
  2616. if (SUCCEEDED(hr))
  2617. {
  2618. if (UIS_HIDDEN == uis)
  2619. {
  2620. bRestricted = true;
  2621. }
  2622. }
  2623. return bRestricted;
  2624. }
  2625. //-----------------------------------------------------------------------------
  2626. // CCplWebViewInfo
  2627. //-----------------------------------------------------------------------------
  2628. class CCplWebViewInfo : public ICplWebViewInfo
  2629. {
  2630. public:
  2631. ~CCplWebViewInfo(void);
  2632. //
  2633. // IUnknown
  2634. //
  2635. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  2636. STDMETHOD_(ULONG, AddRef)(void);
  2637. STDMETHOD_(ULONG, Release)(void);
  2638. //
  2639. // IEnumCplWebViewInfo
  2640. //
  2641. STDMETHOD(get_Header)(IUIElement **ppele);
  2642. STDMETHOD(get_Style)(DWORD *pdwFlags);
  2643. STDMETHOD(EnumTasks)(IEnumUICommand **ppenum);
  2644. static HRESULT CreateInstance(IUIElement *peHeader, IEnumUICommand *penum, DWORD dwStyle, REFIID riid, void **ppvOut);
  2645. private:
  2646. LONG m_cRef;
  2647. IUIElement *m_peHeader; // The webview menu header.
  2648. IEnumUICommand *m_penumUiCommand; // The webview menu tasks.
  2649. DWORD m_dwStyle; // Style flags.
  2650. CCplWebViewInfo(void);
  2651. };
  2652. CCplWebViewInfo::CCplWebViewInfo(
  2653. void
  2654. ) : m_cRef(1),
  2655. m_peHeader(NULL),
  2656. m_penumUiCommand(NULL),
  2657. m_dwStyle(0)
  2658. {
  2659. TraceMsg(TF_LIFE, "CCplWebViewInfo::CCplWebViewInfo, this = 0x%x", this);
  2660. }
  2661. CCplWebViewInfo::~CCplWebViewInfo(
  2662. void
  2663. )
  2664. {
  2665. TraceMsg(TF_LIFE, "CCplWebViewInfo::~CCplWebViewInfo, this = 0x%x", this);
  2666. ATOMICRELEASE(m_peHeader);
  2667. ATOMICRELEASE(m_penumUiCommand);
  2668. }
  2669. HRESULT
  2670. CCplWebViewInfo::CreateInstance( // [static]
  2671. IUIElement *peHeader,
  2672. IEnumUICommand *penum,
  2673. DWORD dwStyle,
  2674. REFIID riid,
  2675. void **ppvOut
  2676. )
  2677. {
  2678. ASSERT(NULL != peHeader);
  2679. ASSERT(NULL != penum);
  2680. ASSERT(NULL != ppvOut);
  2681. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  2682. *ppvOut = NULL;
  2683. HRESULT hr = E_OUTOFMEMORY;
  2684. CCplWebViewInfo *pwvi = new CCplWebViewInfo();
  2685. if (NULL != pwvi)
  2686. {
  2687. hr = pwvi->QueryInterface(riid, ppvOut);
  2688. if (SUCCEEDED(hr))
  2689. {
  2690. (pwvi->m_peHeader = peHeader)->AddRef();
  2691. (pwvi->m_penumUiCommand = penum)->AddRef();
  2692. pwvi->m_dwStyle = dwStyle;
  2693. }
  2694. pwvi->Release();
  2695. }
  2696. return THR(hr);
  2697. }
  2698. STDMETHODIMP
  2699. CCplWebViewInfo::QueryInterface(
  2700. REFIID riid,
  2701. void **ppv
  2702. )
  2703. {
  2704. ASSERT(NULL != ppv);
  2705. ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
  2706. static const QITAB qit[] = {
  2707. QITABENT(CCplWebViewInfo, ICplWebViewInfo),
  2708. { 0 },
  2709. };
  2710. HRESULT hr = QISearch(this, qit, riid, ppv);
  2711. return E_NOINTERFACE == hr ? hr : THR(hr);
  2712. }
  2713. STDMETHODIMP_(ULONG)
  2714. CCplWebViewInfo::AddRef(
  2715. void
  2716. )
  2717. {
  2718. return InterlockedIncrement(&m_cRef);
  2719. }
  2720. STDMETHODIMP_(ULONG)
  2721. CCplWebViewInfo::Release(
  2722. void
  2723. )
  2724. {
  2725. if (InterlockedDecrement(&m_cRef))
  2726. return m_cRef;
  2727. delete this;
  2728. return 0;
  2729. }
  2730. STDMETHODIMP
  2731. CCplWebViewInfo::get_Header(
  2732. IUIElement **ppele
  2733. )
  2734. {
  2735. ASSERT(NULL != ppele);
  2736. ASSERT(!IsBadWritePtr(ppele, sizeof(*ppele)));
  2737. HRESULT hr = S_OK;
  2738. (*ppele = m_peHeader)->AddRef();
  2739. return THR(hr);
  2740. }
  2741. STDMETHODIMP
  2742. CCplWebViewInfo::get_Style(
  2743. DWORD *pdwStyle
  2744. )
  2745. {
  2746. ASSERT(NULL != pdwStyle);
  2747. ASSERT(!IsBadWritePtr(pdwStyle, sizeof(*pdwStyle)));
  2748. *pdwStyle = m_dwStyle;
  2749. return S_OK;
  2750. }
  2751. STDMETHODIMP
  2752. CCplWebViewInfo::EnumTasks(
  2753. IEnumUICommand **ppenum
  2754. )
  2755. {
  2756. ASSERT(NULL != ppenum);
  2757. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  2758. HRESULT hr = S_OK;
  2759. (*ppenum = m_penumUiCommand)->AddRef();
  2760. return THR(hr);
  2761. }
  2762. //-----------------------------------------------------------------------------
  2763. // CEnumCplWebViewInfo
  2764. //-----------------------------------------------------------------------------
  2765. struct ECWVI_ITEM
  2766. {
  2767. eCPWVTYPE eType;
  2768. const CPLINK_DESC **rgpDesc; // Ptr to nul-term array of link desc ptrs.
  2769. bool bRestricted; // Is item restricted from usage?
  2770. bool bEnhancedMenu; // Render as a 'special' list in webview?
  2771. };
  2772. class CEnumCplWebViewInfo : public CObjectWithSite,
  2773. public IEnumCplWebViewInfo
  2774. {
  2775. public:
  2776. ~CEnumCplWebViewInfo(void);
  2777. //
  2778. // IUnknown
  2779. //
  2780. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  2781. STDMETHOD_(ULONG, AddRef)(void);
  2782. STDMETHOD_(ULONG, Release)(void);
  2783. //
  2784. // IEnumCplWebViewInfo
  2785. //
  2786. STDMETHOD(Next)(ULONG celt, ICplWebViewInfo **ppwvi, ULONG *pceltFetched);
  2787. STDMETHOD(Skip)(ULONG celt);
  2788. STDMETHOD(Reset)(void);
  2789. STDMETHOD(Clone)(IEnumCplWebViewInfo **ppenum);
  2790. static HRESULT CreateInstance(IUnknown *punkSite, const ECWVI_ITEM *prgwvi, UINT cItems, REFIID riid, void **ppvOut);
  2791. private:
  2792. LONG m_cRef;
  2793. int m_iCurrent;
  2794. CDpa<ICplWebViewInfo, CDpaDestroyer_Release<ICplWebViewInfo> > m_rgwvi;
  2795. CEnumCplWebViewInfo(void);
  2796. HRESULT _Initialize(IUnknown *punkSite, const ECWVI_ITEM *prgwvi, UINT cItems);
  2797. //
  2798. // Prevent copy.
  2799. //
  2800. CEnumCplWebViewInfo(const CEnumCplWebViewInfo& rhs); // not implemented.
  2801. CEnumCplWebViewInfo& operator = (const CEnumCplWebViewInfo& rhs); // not implemented.
  2802. };
  2803. CEnumCplWebViewInfo::CEnumCplWebViewInfo(
  2804. void
  2805. ) : m_cRef(1),
  2806. m_iCurrent(0)
  2807. {
  2808. TraceMsg(TF_LIFE, "CEnumCplWebViewInfo::CEnumCplWebViewInfo, this = 0x%x", this);
  2809. }
  2810. CEnumCplWebViewInfo::~CEnumCplWebViewInfo(
  2811. void
  2812. )
  2813. {
  2814. TraceMsg(TF_LIFE, "CEnumCplWebViewInfo::~CEnumCplWebViewInfo, this = 0x%x", this);
  2815. }
  2816. HRESULT
  2817. CEnumCplWebViewInfo::CreateInstance(
  2818. IUnknown *punkSite,
  2819. const ECWVI_ITEM *prgwvi,
  2820. UINT cItems,
  2821. REFIID riid,
  2822. void **ppvOut
  2823. )
  2824. {
  2825. ASSERT(NULL != punkSite);
  2826. ASSERT(NULL != prgwvi);
  2827. ASSERT(NULL != ppvOut);
  2828. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  2829. *ppvOut = NULL;
  2830. HRESULT hr = E_OUTOFMEMORY;
  2831. CEnumCplWebViewInfo *pewvi = new CEnumCplWebViewInfo();
  2832. if (NULL != pewvi)
  2833. {
  2834. hr = pewvi->_Initialize(punkSite, prgwvi, cItems);
  2835. if (SUCCEEDED(hr))
  2836. {
  2837. hr = pewvi->QueryInterface(riid, ppvOut);
  2838. }
  2839. pewvi->Release();
  2840. }
  2841. return THR(hr);
  2842. }
  2843. STDMETHODIMP
  2844. CEnumCplWebViewInfo::QueryInterface(
  2845. REFIID riid,
  2846. void **ppv
  2847. )
  2848. {
  2849. ASSERT(NULL != ppv);
  2850. ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
  2851. static const QITAB qit[] = {
  2852. QITABENT(CEnumCplWebViewInfo, IEnumCplWebViewInfo),
  2853. QITABENT(CEnumCplWebViewInfo, IObjectWithSite),
  2854. { 0 },
  2855. };
  2856. HRESULT hr = QISearch(this, qit, riid, ppv);
  2857. return E_NOINTERFACE == hr ? hr : THR(hr);
  2858. }
  2859. STDMETHODIMP_(ULONG)
  2860. CEnumCplWebViewInfo::AddRef(
  2861. void
  2862. )
  2863. {
  2864. return InterlockedIncrement(&m_cRef);
  2865. }
  2866. STDMETHODIMP_(ULONG)
  2867. CEnumCplWebViewInfo::Release(
  2868. void
  2869. )
  2870. {
  2871. if (InterlockedDecrement(&m_cRef))
  2872. return m_cRef;
  2873. delete this;
  2874. return 0;
  2875. }
  2876. STDMETHODIMP
  2877. CEnumCplWebViewInfo::Next(
  2878. ULONG celt,
  2879. ICplWebViewInfo **ppwvi,
  2880. ULONG *pceltFetched
  2881. )
  2882. {
  2883. ASSERT(NULL != ppwvi);
  2884. ASSERT(!IsBadWritePtr(ppwvi, sizeof(*ppwvi) * celt));
  2885. ULONG celtFetched = 0;
  2886. while(m_iCurrent < m_rgwvi.Count() && 0 < celt)
  2887. {
  2888. *ppwvi = m_rgwvi.Get(m_iCurrent++);
  2889. ASSERT(NULL != *ppwvi);
  2890. (*ppwvi)->AddRef();
  2891. celt--;
  2892. celtFetched++;
  2893. ppwvi++;
  2894. }
  2895. if (NULL != pceltFetched)
  2896. {
  2897. *pceltFetched = celtFetched;
  2898. }
  2899. return 0 == celt ? S_OK : S_FALSE;
  2900. }
  2901. STDMETHODIMP
  2902. CEnumCplWebViewInfo::Reset(
  2903. void
  2904. )
  2905. {
  2906. m_iCurrent = 0;
  2907. return S_OK;
  2908. }
  2909. STDMETHODIMP
  2910. CEnumCplWebViewInfo::Skip(
  2911. ULONG n
  2912. )
  2913. {
  2914. while(0 < n-- && m_iCurrent < m_rgwvi.Count())
  2915. {
  2916. m_iCurrent++;
  2917. }
  2918. return 0 == n ? S_OK : S_FALSE;
  2919. }
  2920. STDMETHODIMP
  2921. CEnumCplWebViewInfo::Clone(
  2922. IEnumCplWebViewInfo **ppenum
  2923. )
  2924. {
  2925. ASSERT(NULL != ppenum);
  2926. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  2927. *ppenum = NULL;
  2928. HRESULT hr = E_OUTOFMEMORY;
  2929. CEnumCplWebViewInfo *penum = new CEnumCplWebViewInfo();
  2930. if (NULL != *ppenum)
  2931. {
  2932. for (int i = 0; SUCCEEDED(hr) && i < m_rgwvi.Count(); i++)
  2933. {
  2934. ICplWebViewInfo *pwvi = m_rgwvi.Get(i);
  2935. ASSERT(NULL != pwvi);
  2936. if (-1 != penum->m_rgwvi.Append(pwvi))
  2937. {
  2938. pwvi->AddRef();
  2939. }
  2940. else
  2941. {
  2942. hr = E_OUTOFMEMORY;
  2943. }
  2944. }
  2945. if (SUCCEEDED(hr))
  2946. {
  2947. hr = penum->QueryInterface(IID_IEnumCplWebViewInfo, (void **)ppenum);
  2948. }
  2949. penum->Release();
  2950. }
  2951. return THR(hr);
  2952. }
  2953. HRESULT
  2954. CEnumCplWebViewInfo::_Initialize(
  2955. IUnknown *punkSite,
  2956. const ECWVI_ITEM *prgwvi,
  2957. UINT cItems
  2958. )
  2959. {
  2960. ASSERT(NULL != punkSite);
  2961. ASSERT(NULL != prgwvi);
  2962. IUnknown *punk;
  2963. HRESULT hr = QueryInterface(IID_IUnknown, (void **)&punk);
  2964. if (SUCCEEDED(hr))
  2965. {
  2966. hr = IUnknown_SetSite(punk, punkSite);
  2967. if (SUCCEEDED(hr))
  2968. {
  2969. for (UINT i = 0; i < cItems; i++)
  2970. {
  2971. if (!prgwvi[i].bRestricted)
  2972. {
  2973. IEnumUICommand *penum;
  2974. hr = CEnumCommand::CreateInstance(CObjectWithSite::_punkSite,
  2975. prgwvi[i].rgpDesc,
  2976. IID_IEnumUICommand,
  2977. (void **)&penum);
  2978. if (SUCCEEDED(hr))
  2979. {
  2980. IUIElement *peHeader;
  2981. hr = CplNamespace_CreateWebViewHeaderElement(prgwvi[i].eType, &peHeader);
  2982. if (SUCCEEDED(hr))
  2983. {
  2984. DWORD dwStyle = 0;
  2985. if (prgwvi[i].bEnhancedMenu)
  2986. {
  2987. dwStyle |= SFVMWVF_SPECIALTASK;
  2988. }
  2989. ICplWebViewInfo *pwvi;
  2990. hr = CCplWebViewInfo::CreateInstance(peHeader, penum, dwStyle, IID_ICplWebViewInfo, (void **)&pwvi);
  2991. if (SUCCEEDED(hr))
  2992. {
  2993. if (-1 == m_rgwvi.Append(pwvi))
  2994. {
  2995. pwvi->Release();
  2996. hr = E_OUTOFMEMORY;
  2997. }
  2998. }
  2999. peHeader->Release();
  3000. }
  3001. penum->Release();
  3002. }
  3003. }
  3004. }
  3005. }
  3006. punk->Release();
  3007. }
  3008. return THR(hr);
  3009. }
  3010. //-----------------------------------------------------------------------------
  3011. // CCplCategory
  3012. //-----------------------------------------------------------------------------
  3013. class CCplCategory : public CObjectWithSite,
  3014. public ICplCategory
  3015. {
  3016. public:
  3017. ~CCplCategory(void);
  3018. //
  3019. // IUnknown
  3020. //
  3021. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  3022. STDMETHOD_(ULONG, AddRef)(void);
  3023. STDMETHOD_(ULONG, Release)(void);
  3024. //
  3025. // ICplCategory
  3026. //
  3027. STDMETHOD(GetCategoryID)(eCPCAT *pID);
  3028. STDMETHOD(GetUiCommand)(IUICommand **ppele);
  3029. STDMETHOD(EnumTasks)(IEnumUICommand **ppenum);
  3030. STDMETHOD(EnumCplApplets)(IEnumUICommand **ppenum);
  3031. STDMETHOD(EnumWebViewInfo)(DWORD dwFlags, IEnumCplWebViewInfo **ppenum);
  3032. STDMETHOD(GetHelpURL)(LPWSTR pszURL, UINT cchURL);
  3033. static HRESULT CreateInstance(const CPCAT_DESC *pDesc, const CDpaUiCommand& rgCplApplets, REFIID riid, void **ppvOut);
  3034. private:
  3035. LONG m_cRef;
  3036. const CPCAT_DESC *m_pDesc; // Initialization data.
  3037. CDpaUiCommand m_rgCplApplets; // Cached list of CPL applet links.
  3038. CCplCategory(void);
  3039. //
  3040. // Prevent copy.
  3041. //
  3042. CCplCategory(const CCplCategory& rhs); // not implemented.
  3043. CCplCategory& operator = (const CCplCategory& rhs); // not implemented.
  3044. HRESULT _Initialize(const CPCAT_DESC *pDesc, const CDpaUiCommand& rgCplApplets);
  3045. bool _CplAppletsLoaded(void) const;
  3046. };
  3047. CCplCategory::CCplCategory(
  3048. void
  3049. ) : m_cRef(1),
  3050. m_pDesc(NULL)
  3051. {
  3052. TraceMsg(TF_LIFE, "CCplCategory::CCplCategory, this = 0x%x", this);
  3053. }
  3054. CCplCategory::~CCplCategory(
  3055. void
  3056. )
  3057. {
  3058. TraceMsg(TF_LIFE, "CCplCategory::~CCplCategory, this = 0x%x", this);
  3059. }
  3060. HRESULT
  3061. CCplCategory::CreateInstance(
  3062. const CPCAT_DESC *pDesc,
  3063. const CDpaUiCommand& rgCplApplets,
  3064. REFIID riid,
  3065. void **ppvOut
  3066. )
  3067. {
  3068. ASSERT(NULL != pDesc);
  3069. ASSERT(NULL != ppvOut);
  3070. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  3071. *ppvOut = NULL;
  3072. HRESULT hr = E_OUTOFMEMORY;
  3073. CCplCategory *pc = new CCplCategory();
  3074. if (NULL != pc)
  3075. {
  3076. hr = pc->_Initialize(pDesc, rgCplApplets);
  3077. if (SUCCEEDED(hr))
  3078. {
  3079. hr = pc->QueryInterface(riid, ppvOut);
  3080. }
  3081. pc->Release();
  3082. }
  3083. return THR(hr);
  3084. }
  3085. STDMETHODIMP
  3086. CCplCategory::QueryInterface(
  3087. REFIID riid,
  3088. void **ppv
  3089. )
  3090. {
  3091. ASSERT(NULL != ppv);
  3092. ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
  3093. static const QITAB qit[] = {
  3094. QITABENT(CCplCategory, ICplCategory),
  3095. QITABENT(CCplCategory, IObjectWithSite),
  3096. { 0 },
  3097. };
  3098. HRESULT hr = QISearch(this, qit, riid, ppv);
  3099. return E_NOINTERFACE == hr ? hr : THR(hr);
  3100. }
  3101. STDMETHODIMP_(ULONG)
  3102. CCplCategory::AddRef(
  3103. void
  3104. )
  3105. {
  3106. return InterlockedIncrement(&m_cRef);
  3107. }
  3108. STDMETHODIMP_(ULONG)
  3109. CCplCategory::Release(
  3110. void
  3111. )
  3112. {
  3113. if (InterlockedDecrement(&m_cRef))
  3114. return m_cRef;
  3115. delete this;
  3116. return 0;
  3117. }
  3118. STDMETHODIMP
  3119. CCplCategory::GetUiCommand(
  3120. IUICommand **ppc
  3121. )
  3122. {
  3123. DBG_ENTER(FTF_CPANEL, "CCplCategory::GetUiCommand");
  3124. ASSERT(NULL != m_pDesc);
  3125. ASSERT(NULL != m_pDesc->pLink);
  3126. ASSERT(NULL != ppc);
  3127. ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
  3128. HRESULT hr = CplNamespace_CreateUiCommand(CObjectWithSite::_punkSite,
  3129. *(m_pDesc->pLink),
  3130. ppc);
  3131. if (SUCCEEDED(hr))
  3132. {
  3133. hr = IUnknown_SetSite(*ppc, CObjectWithSite::_punkSite);
  3134. }
  3135. DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::GetUiCommand", hr);
  3136. return THR(hr);
  3137. }
  3138. STDMETHODIMP
  3139. CCplCategory::EnumWebViewInfo(
  3140. DWORD dwFlags,
  3141. IEnumCplWebViewInfo **ppenum
  3142. )
  3143. {
  3144. DBG_ENTER(FTF_CPANEL, "CCplCategory::EnumWebViewInfo");
  3145. ASSERT(NULL != m_pDesc);
  3146. ASSERT(NULL != ppenum);
  3147. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  3148. UNREFERENCED_PARAMETER(dwFlags);
  3149. const ECWVI_ITEM rgItems[] = {
  3150. { eCPWVTYPE_SEEALSO, m_pDesc->slinks.ppSeeAlsoLinks, false, false },
  3151. { eCPWVTYPE_TROUBLESHOOT, m_pDesc->slinks.ppTroubleshootLinks, false, false },
  3152. { eCPWVTYPE_LEARNABOUT, m_pDesc->slinks.ppLearnAboutLinks, false, false }
  3153. };
  3154. HRESULT hr = CEnumCplWebViewInfo::CreateInstance(CObjectWithSite::_punkSite,
  3155. rgItems,
  3156. ARRAYSIZE(rgItems),
  3157. IID_IEnumCplWebViewInfo,
  3158. (void **)ppenum);
  3159. DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::EnumWebViewInfo", hr);
  3160. return THR(hr);
  3161. }
  3162. STDMETHODIMP
  3163. CCplCategory::EnumTasks(
  3164. IEnumUICommand **ppenum
  3165. )
  3166. {
  3167. DBG_ENTER(FTF_CPANEL, "CCplCategory::EnumTasks");
  3168. ASSERT(NULL != m_pDesc);
  3169. ASSERT(NULL != ppenum);
  3170. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  3171. HRESULT hr = CEnumCommand::CreateInstance(CObjectWithSite::_punkSite,
  3172. m_pDesc->ppTaskLinks,
  3173. IID_IEnumUICommand,
  3174. (void **)ppenum);
  3175. DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::EnumTasks", hr);
  3176. return THR(hr);
  3177. }
  3178. STDMETHODIMP
  3179. CCplCategory::EnumCplApplets(
  3180. IEnumUICommand **ppenum
  3181. )
  3182. {
  3183. DBG_ENTER(FTF_CPANEL, "CCplCategory::EnumCplApplets");
  3184. ASSERT(NULL != ppenum);
  3185. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  3186. HRESULT hr = CEnumCommand::CreateInstance(CObjectWithSite::_punkSite,
  3187. m_rgCplApplets,
  3188. IID_IEnumUICommand,
  3189. (void **)ppenum);
  3190. DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::EnumCplApplets", hr);
  3191. return THR(hr);
  3192. }
  3193. STDMETHODIMP
  3194. CCplCategory::GetCategoryID(
  3195. eCPCAT *pID
  3196. )
  3197. {
  3198. ASSERT(NULL != pID);
  3199. ASSERT(!IsBadWritePtr(pID, sizeof(*pID)));
  3200. *pID = m_pDesc->idCategory;
  3201. return S_OK;
  3202. }
  3203. STDMETHODIMP
  3204. CCplCategory::GetHelpURL(
  3205. LPWSTR pszURL,
  3206. UINT cchURL
  3207. )
  3208. {
  3209. ASSERT(NULL != pszURL);
  3210. ASSERT(!IsBadWritePtr(pszURL, cchURL * sizeof(*pszURL)));
  3211. return CPL::BuildHssHelpURL(m_pDesc->pszHelpSelection, pszURL, cchURL);
  3212. }
  3213. HRESULT
  3214. CCplCategory::_Initialize(
  3215. const CPCAT_DESC *pDesc,
  3216. const CDpaUiCommand& rgCplApplets
  3217. )
  3218. {
  3219. ASSERT(NULL != pDesc);
  3220. ASSERT(NULL == m_pDesc);
  3221. m_pDesc = pDesc;
  3222. HRESULT hr = CplNamespace_CopyCommandArray(rgCplApplets, &m_rgCplApplets);
  3223. return THR(hr);
  3224. }
  3225. //-----------------------------------------------------------------------------
  3226. // CTriState
  3227. // This is a trivial class to allow representation of a uninitialized boolean
  3228. // value. Used by CCplNamespace for it's storage of cached 'restriction'
  3229. // values. Internally, -1 == 'uninitialized, 0 == false and 1 == true.
  3230. //-----------------------------------------------------------------------------
  3231. class CTriState
  3232. {
  3233. public:
  3234. CTriState(void)
  3235. : m_iVal(-1) { }
  3236. operator bool() const
  3237. { ASSERT(!_Invalid()); return (!_Invalid() ? !!m_iVal : false); }
  3238. CTriState& operator = (bool bValue)
  3239. { m_iVal = bValue ? 1 : 0; return *this; }
  3240. bool IsInvalid(void) const
  3241. { return _Invalid(); }
  3242. private:
  3243. int m_iVal;
  3244. void _Set(bool bValue)
  3245. { m_iVal = bValue ? 1 : 0; }
  3246. bool _Invalid(void) const
  3247. { return (-1 == m_iVal); }
  3248. };
  3249. //-----------------------------------------------------------------------------
  3250. // CCplNamespace
  3251. //-----------------------------------------------------------------------------
  3252. class CCplNamespace : public CObjectWithSite,
  3253. public ICplNamespace
  3254. {
  3255. public:
  3256. ~CCplNamespace(void);
  3257. //
  3258. // IUnknown
  3259. //
  3260. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  3261. STDMETHOD_(ULONG, AddRef)(void);
  3262. STDMETHOD_(ULONG, Release)(void);
  3263. //
  3264. // ICplNamespace
  3265. //
  3266. STDMETHOD(GetCategory)(eCPCAT eCategory, ICplCategory **ppcat);
  3267. STDMETHOD(EnumWebViewInfo)(DWORD dwFlags, IEnumCplWebViewInfo **ppenum);
  3268. STDMETHOD(EnumClassicWebViewInfo)(DWORD dwFlags, IEnumCplWebViewInfo **ppenum);
  3269. STDMETHOD(RefreshIDs)(IEnumIDList *penumIDs);
  3270. STDMETHOD_(BOOL, IsServer)(void);
  3271. STDMETHOD_(BOOL, IsProfessional)(void);
  3272. STDMETHOD_(BOOL, IsPersonal)(void);
  3273. STDMETHOD_(BOOL, IsUserAdmin)(void);
  3274. STDMETHOD_(BOOL, IsUserOwner)(void);
  3275. STDMETHOD_(BOOL, IsUserStandard)(void);
  3276. STDMETHOD_(BOOL, IsUserLimited)(void);
  3277. STDMETHOD_(BOOL, IsUserGuest)(void);
  3278. STDMETHOD_(BOOL, IsOnDomain)(void);
  3279. STDMETHOD_(BOOL, IsX86)(void);
  3280. STDMETHOD_(BOOL, AllowUserManager)(void);
  3281. STDMETHOD_(BOOL, UsePersonalUserManager)(void);
  3282. STDMETHOD_(BOOL, AllowDeskCpl)(void);
  3283. STDMETHOD_(BOOL, AllowDeskCplTab_Background)(void);
  3284. STDMETHOD_(BOOL, AllowDeskCplTab_Screensaver)(void);
  3285. STDMETHOD_(BOOL, AllowDeskCplTab_Appearance)(void);
  3286. STDMETHOD_(BOOL, AllowDeskCplTab_Settings)(void);
  3287. static HRESULT CreateInstance(IEnumIDList *penumIDs, REFIID riid, void **ppvOut);
  3288. private:
  3289. LONG m_cRef;
  3290. ICplCategory *m_rgpCategories[eCPCAT_NUMCATEGORIES];
  3291. CDpaUiCommand m_rgCplApplets[eCPCAT_NUMCATEGORIES];
  3292. IEnumIDList *m_penumIDs;
  3293. CTriState m_SkuSvr;
  3294. CTriState m_SkuPro;
  3295. CTriState m_SkuPer;
  3296. CTriState m_Admin;
  3297. CTriState m_UserOwner;
  3298. CTriState m_UserStandard;
  3299. CTriState m_UserLimited;
  3300. CTriState m_UserGuest;
  3301. CTriState m_Domain;
  3302. CTriState m_AllowUserManager;
  3303. CTriState m_PersonalUserManager;
  3304. CTriState m_AllowDeskCpl;
  3305. CTriState m_rgAllowDeskCplTabs[CPLTAB_DESK_MAX];
  3306. CCplNamespace(void);
  3307. //
  3308. // Prevent copy.
  3309. //
  3310. CCplNamespace(const CCplNamespace& rhs); // not implemented.
  3311. CCplNamespace& operator = (const CCplNamespace& rhs); // not implemented.
  3312. HRESULT _Initialize(IEnumIDList *penumIDs);
  3313. HRESULT _SetIDList(IEnumIDList *penumIDs);
  3314. HRESULT _IsValidCategoryID(int iCategory) const;
  3315. HRESULT _CategorizeCplApplets(void);
  3316. HRESULT _LoadSeeAlsoLinks(void);
  3317. HRESULT _AddSeeAlso(IUICommand *pc);
  3318. HRESULT _CategorizeCplApplet(IShellFolder2 *psf2Cpanel, LPCITEMIDLIST pidlItem);
  3319. BOOL _UserAcctType(CTriState *pts);
  3320. void _GetUserAccountType(void);
  3321. BOOL _AllowDeskCplTab(eDESKCPLTAB eTab);
  3322. void _DestroyCategories(void);
  3323. void _ClearCplApplets(void);
  3324. };
  3325. CCplNamespace::CCplNamespace(
  3326. void
  3327. ) : m_cRef(1),
  3328. m_penumIDs(NULL)
  3329. {
  3330. TraceMsg(TF_LIFE, "CCplNamespace::CCplNamespace, this = 0x%x", this);
  3331. ZeroMemory(m_rgpCategories, ARRAYSIZE(m_rgpCategories) * sizeof(m_rgpCategories[0]));
  3332. }
  3333. CCplNamespace::~CCplNamespace(
  3334. void
  3335. )
  3336. {
  3337. TraceMsg(TF_LIFE, "CCplNamespace::~CCplNamespace, this = 0x%x", this);
  3338. _DestroyCategories();
  3339. ATOMICRELEASE(m_penumIDs);
  3340. }
  3341. HRESULT
  3342. CCplNamespace::CreateInstance(
  3343. IEnumIDList *penumIDs,
  3344. REFIID riid,
  3345. void **ppvOut
  3346. )
  3347. {
  3348. ASSERT(NULL != penumIDs);
  3349. ASSERT(NULL != ppvOut);
  3350. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  3351. *ppvOut = NULL;
  3352. HRESULT hr = E_OUTOFMEMORY;
  3353. CCplNamespace *pns = new CCplNamespace();
  3354. if (NULL != pns)
  3355. {
  3356. hr = pns->_Initialize(penumIDs);
  3357. if (SUCCEEDED(hr))
  3358. {
  3359. hr = pns->QueryInterface(riid, ppvOut);
  3360. }
  3361. pns->Release();
  3362. }
  3363. return THR(hr);
  3364. }
  3365. STDMETHODIMP
  3366. CCplNamespace::QueryInterface(
  3367. REFIID riid,
  3368. void **ppv
  3369. )
  3370. {
  3371. ASSERT(NULL != ppv);
  3372. ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
  3373. static const QITAB qit[] = {
  3374. QITABENT(CCplNamespace, ICplNamespace),
  3375. QITABENT(CCplNamespace, IObjectWithSite),
  3376. { 0 },
  3377. };
  3378. HRESULT hr = QISearch(this, qit, riid, ppv);
  3379. return E_NOINTERFACE == hr ? hr : THR(hr);
  3380. }
  3381. STDMETHODIMP_(ULONG)
  3382. CCplNamespace::AddRef(
  3383. void
  3384. )
  3385. {
  3386. TraceMsg(TF_LIFE, "CCplNamespace::AddRef %d->%d", m_cRef, m_cRef+1);
  3387. return InterlockedIncrement(&m_cRef);
  3388. }
  3389. STDMETHODIMP_(ULONG)
  3390. CCplNamespace::Release(
  3391. void
  3392. )
  3393. {
  3394. TraceMsg(TF_LIFE, "CCplNamespace::Release %d<-%d", m_cRef-1, m_cRef);
  3395. if (InterlockedDecrement(&m_cRef))
  3396. return m_cRef;
  3397. delete this;
  3398. return 0;
  3399. }
  3400. STDMETHODIMP
  3401. CCplNamespace::EnumWebViewInfo(
  3402. DWORD dwFlags,
  3403. IEnumCplWebViewInfo **ppenum
  3404. )
  3405. {
  3406. DBG_ENTER(FTF_CPANEL, "CCplNamespace::EnumWebViewInfo");
  3407. ASSERT(NULL != ppenum);
  3408. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  3409. const bool bNoViewSwitch = (0 != (CPVIEW_EF_NOVIEWSWITCH & dwFlags));
  3410. const ECWVI_ITEM rgItems[] = {
  3411. { eCPWVTYPE_CPANEL, g_rgpLink_Cpl_SwToClassicView, bNoViewSwitch, true },
  3412. { eCPWVTYPE_SEEALSO, g_rgpLink_Cpl_SeeAlso, false, false }
  3413. };
  3414. HRESULT hr = CEnumCplWebViewInfo::CreateInstance(CObjectWithSite::_punkSite,
  3415. rgItems,
  3416. ARRAYSIZE(rgItems),
  3417. IID_IEnumCplWebViewInfo,
  3418. (void **)ppenum);
  3419. DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::EnumWebViewInfo", hr);
  3420. return THR(hr);
  3421. }
  3422. STDMETHODIMP
  3423. CCplNamespace::EnumClassicWebViewInfo(
  3424. DWORD dwFlags,
  3425. IEnumCplWebViewInfo **ppenum
  3426. )
  3427. {
  3428. DBG_ENTER(FTF_CPANEL, "CCplNamespace::EnumClassicWebViewInfo");
  3429. ASSERT(NULL != ppenum);
  3430. ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
  3431. const bool bNoViewSwitch = (0 != (CPVIEW_EF_NOVIEWSWITCH & dwFlags));
  3432. const ECWVI_ITEM rgItems[] = {
  3433. { eCPWVTYPE_CPANEL, g_rgpLink_Cpl_SwToCategoryView, bNoViewSwitch, true },
  3434. { eCPWVTYPE_SEEALSO, g_rgpLink_Cpl_SeeAlso, false, false }
  3435. };
  3436. HRESULT hr = CEnumCplWebViewInfo::CreateInstance(CObjectWithSite::_punkSite,
  3437. rgItems,
  3438. ARRAYSIZE(rgItems),
  3439. IID_IEnumCplWebViewInfo,
  3440. (void **)ppenum);
  3441. DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::EnumClassicWebViewInfo", hr);
  3442. return THR(hr);
  3443. }
  3444. STDMETHODIMP
  3445. CCplNamespace::GetCategory(
  3446. eCPCAT eCategory,
  3447. ICplCategory **ppcat
  3448. )
  3449. {
  3450. DBG_ENTER(FTF_CPANEL, "CCplNamespace::GetCategory");
  3451. TraceMsg(FTF_CPANEL, "Category ID = %d", eCategory);
  3452. ASSERT(S_OK == _IsValidCategoryID(eCategory));
  3453. ASSERT(NULL != ppcat);
  3454. ASSERT(!IsBadWritePtr(ppcat, sizeof(*ppcat)));
  3455. HRESULT hr = S_OK;
  3456. *ppcat = NULL;
  3457. if (NULL == m_rgpCategories[eCategory])
  3458. {
  3459. hr = CCplCategory::CreateInstance(g_rgpCplCatInfo[eCategory],
  3460. m_rgCplApplets[eCategory],
  3461. IID_ICplCategory,
  3462. (void **)&m_rgpCategories[eCategory]);
  3463. if (SUCCEEDED(hr))
  3464. {
  3465. ASSERT(NULL != CObjectWithSite::_punkSite);
  3466. hr = IUnknown_SetSite(m_rgpCategories[eCategory], CObjectWithSite::_punkSite);
  3467. }
  3468. }
  3469. if (SUCCEEDED(hr))
  3470. {
  3471. *ppcat = m_rgpCategories[eCategory];
  3472. (*ppcat)->AddRef();
  3473. }
  3474. DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::GetCategory", hr);
  3475. return THR(hr);
  3476. }
  3477. STDMETHODIMP
  3478. CCplNamespace::RefreshIDs(
  3479. IEnumIDList *penumIDs
  3480. )
  3481. {
  3482. return _SetIDList(penumIDs);
  3483. }
  3484. BOOL CCplNamespace::IsX86(void)
  3485. {
  3486. #ifdef _X86_
  3487. return true;
  3488. #else
  3489. return false;
  3490. #endif
  3491. }
  3492. BOOL CCplNamespace::IsServer(void)
  3493. {
  3494. if (m_SkuSvr.IsInvalid())
  3495. {
  3496. m_SkuSvr = !!IsOsServer();
  3497. }
  3498. return m_SkuSvr;
  3499. }
  3500. BOOL CCplNamespace::IsPersonal(void)
  3501. {
  3502. if (m_SkuPer.IsInvalid())
  3503. {
  3504. m_SkuPer = !!IsOsPersonal();
  3505. }
  3506. return m_SkuPer;
  3507. }
  3508. BOOL CCplNamespace::IsProfessional(void)
  3509. {
  3510. if (m_SkuPro.IsInvalid())
  3511. {
  3512. m_SkuPro = !!IsOsProfessional();
  3513. }
  3514. return m_SkuPro;
  3515. }
  3516. BOOL CCplNamespace::IsOnDomain(void)
  3517. {
  3518. if (m_Domain.IsInvalid())
  3519. {
  3520. m_Domain = !!IsConnectedToDomain();
  3521. }
  3522. return m_Domain;
  3523. }
  3524. BOOL CCplNamespace::IsUserAdmin(void)
  3525. {
  3526. if (m_Admin.IsInvalid())
  3527. {
  3528. m_Admin = !!CPL::IsUserAdmin();
  3529. }
  3530. return m_Admin;
  3531. }
  3532. BOOL CCplNamespace::IsUserOwner(void)
  3533. {
  3534. return _UserAcctType(&m_UserOwner);
  3535. }
  3536. BOOL CCplNamespace::IsUserStandard(void)
  3537. {
  3538. return _UserAcctType(&m_UserStandard);
  3539. }
  3540. BOOL CCplNamespace::IsUserLimited(void)
  3541. {
  3542. return _UserAcctType(&m_UserLimited);
  3543. }
  3544. BOOL CCplNamespace::IsUserGuest(void)
  3545. {
  3546. return _UserAcctType(&m_UserGuest);
  3547. }
  3548. BOOL CCplNamespace::UsePersonalUserManager(void)
  3549. {
  3550. if (m_PersonalUserManager.IsInvalid())
  3551. {
  3552. m_PersonalUserManager = (IsX86() && (IsPersonal() || (IsProfessional() && !IsOnDomain())));
  3553. }
  3554. return m_PersonalUserManager;
  3555. }
  3556. BOOL CCplNamespace::AllowUserManager(void)
  3557. {
  3558. if (m_AllowUserManager.IsInvalid())
  3559. {
  3560. m_AllowUserManager = IsAppletEnabled(L"nusrmgr.cpl", MAKEINTRESOURCEW(IDS_CPL_USERACCOUNTS));
  3561. }
  3562. return m_AllowUserManager;
  3563. }
  3564. BOOL CCplNamespace::_AllowDeskCplTab(eDESKCPLTAB eTab)
  3565. {
  3566. if (m_rgAllowDeskCplTabs[eTab].IsInvalid())
  3567. {
  3568. m_rgAllowDeskCplTabs[eTab] = DeskCPL_IsTabPresent(eTab);
  3569. }
  3570. return m_rgAllowDeskCplTabs[eTab];
  3571. }
  3572. BOOL CCplNamespace::AllowDeskCplTab_Background(void)
  3573. {
  3574. return _AllowDeskCplTab(CPLTAB_DESK_BACKGROUND);
  3575. }
  3576. BOOL CCplNamespace::AllowDeskCplTab_Screensaver(void)
  3577. {
  3578. return _AllowDeskCplTab(CPLTAB_DESK_SCREENSAVER);
  3579. }
  3580. BOOL CCplNamespace::AllowDeskCplTab_Appearance(void)
  3581. {
  3582. return _AllowDeskCplTab(CPLTAB_DESK_APPEARANCE);
  3583. }
  3584. BOOL CCplNamespace::AllowDeskCplTab_Settings(void)
  3585. {
  3586. return _AllowDeskCplTab(CPLTAB_DESK_SETTINGS);
  3587. }
  3588. BOOL CCplNamespace::AllowDeskCpl(void)
  3589. {
  3590. if (m_AllowDeskCpl.IsInvalid())
  3591. {
  3592. m_AllowDeskCpl = IsAppletEnabled(L"desk.cpl", MAKEINTRESOURCEW(IDS_CPL_DISPLAY));
  3593. }
  3594. return m_AllowDeskCpl;
  3595. }
  3596. //
  3597. // Retrieves the account type for the current user and updates
  3598. // the cached account type members accordingly.
  3599. //
  3600. void
  3601. CCplNamespace::_GetUserAccountType(void)
  3602. {
  3603. eACCOUNTTYPE eType;
  3604. if (SUCCEEDED(THR(CPL::GetUserAccountType(&eType))))
  3605. {
  3606. m_UserLimited = (eACCOUNTTYPE_LIMITED == eType);
  3607. m_UserStandard = (eACCOUNTTYPE_STANDARD == eType);
  3608. m_UserGuest = (eACCOUNTTYPE_GUEST == eType);
  3609. m_UserOwner = (eACCOUNTTYPE_OWNER == eType);
  3610. }
  3611. }
  3612. //
  3613. // Determins the state of a given account type member.
  3614. //
  3615. BOOL
  3616. CCplNamespace::_UserAcctType(CTriState *pts)
  3617. {
  3618. if (pts->IsInvalid())
  3619. {
  3620. _GetUserAccountType();
  3621. }
  3622. return *pts;
  3623. }
  3624. HRESULT
  3625. CCplNamespace::_IsValidCategoryID(
  3626. int iCategory
  3627. ) const
  3628. {
  3629. HRESULT hr = E_FAIL;
  3630. if (0 <= iCategory && ARRAYSIZE(m_rgpCategories) > iCategory)
  3631. {
  3632. hr = S_OK;
  3633. }
  3634. return THR(hr);
  3635. }
  3636. HRESULT
  3637. CCplNamespace::_Initialize(
  3638. IEnumIDList *penumIDs
  3639. )
  3640. {
  3641. ASSERT(NULL != penumIDs);
  3642. HRESULT hr = _SetIDList(penumIDs);
  3643. return THR(hr);
  3644. }
  3645. HRESULT
  3646. CCplNamespace::_SetIDList(
  3647. IEnumIDList *penumIDs
  3648. )
  3649. {
  3650. DBG_ENTER(FTF_CPANEL, "CCplNamespace::_SetIDList");
  3651. ASSERT(NULL != penumIDs);
  3652. ATOMICRELEASE(m_penumIDs);
  3653. (m_penumIDs = penumIDs)->AddRef();
  3654. //
  3655. // We have a new set of IDs so we need to re-categorize them.
  3656. //
  3657. HRESULT hr = _CategorizeCplApplets();
  3658. DBG_EXIT(FTF_CPANEL, "CCplNamespace::_SetIDList");
  3659. return THR(hr);
  3660. }
  3661. //
  3662. // Destroy all category objects in our array of categories.
  3663. //
  3664. void
  3665. CCplNamespace::_DestroyCategories(
  3666. void
  3667. )
  3668. {
  3669. DBG_ENTER(FTF_CPANEL, "CCplNamespace::_DestroyCategories");
  3670. for (int i = 0; i < ARRAYSIZE(m_rgpCategories); i++)
  3671. {
  3672. ATOMICRELEASE(m_rgpCategories[i]);
  3673. }
  3674. DBG_EXIT(FTF_CPANEL, "CCplNamespace::_DestroyCategories");
  3675. }
  3676. void
  3677. CCplNamespace::_ClearCplApplets(
  3678. void
  3679. )
  3680. {
  3681. DBG_ENTER(FTF_CPANEL, "CCplNamespace::_ClearCplApplets");
  3682. for (int i = 0; i < ARRAYSIZE(m_rgCplApplets); i++)
  3683. {
  3684. m_rgCplApplets[i].Clear();
  3685. }
  3686. DBG_EXIT(FTF_CPANEL, "CCplNamespace::_ClearCplApplets");
  3687. }
  3688. //
  3689. // Load and categorize all of the CPL applets in the Control Panel folder.
  3690. //
  3691. HRESULT
  3692. CCplNamespace::_CategorizeCplApplets(
  3693. void
  3694. )
  3695. {
  3696. DBG_ENTER(FTF_CPANEL, "CCplNamespace::_CategorizeCplApplets");
  3697. //
  3698. // Destroy any existing categories and CPL applets that we have
  3699. // already categorized.
  3700. //
  3701. _DestroyCategories();
  3702. _ClearCplApplets();
  3703. LPITEMIDLIST pidlFolder;
  3704. HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_CONTROLS, &pidlFolder);
  3705. if (SUCCEEDED(hr))
  3706. {
  3707. IShellFolder *psfDesktop;
  3708. hr = SHGetDesktopFolder(&psfDesktop);
  3709. if (SUCCEEDED(hr))
  3710. {
  3711. IShellFolder2 *psf2Cpanel;
  3712. hr = psfDesktop->BindToObject(pidlFolder, NULL, IID_IShellFolder2, (void **)&psf2Cpanel);
  3713. if (SUCCEEDED(hr))
  3714. {
  3715. LPITEMIDLIST pidlItem;
  3716. ULONG celt = 0;
  3717. while(S_OK == (hr = m_penumIDs->Next(1, &pidlItem, &celt)))
  3718. {
  3719. //
  3720. // Note that we continue the enumeration if loading a
  3721. // particular applet fails.
  3722. //
  3723. _CategorizeCplApplet(psf2Cpanel, pidlItem);
  3724. ILFree(pidlItem);
  3725. }
  3726. psf2Cpanel->Release();
  3727. }
  3728. psfDesktop->Release();
  3729. }
  3730. ILFree(pidlFolder);
  3731. }
  3732. DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::_CategorizeCplApplets", hr);
  3733. return THR(hr);
  3734. }
  3735. //
  3736. // Load one CPL applet into the category's DPA of associated CPL applets.
  3737. //
  3738. HRESULT
  3739. CCplNamespace::_CategorizeCplApplet(
  3740. IShellFolder2 *psf2Cpanel,
  3741. LPCITEMIDLIST pidlItem
  3742. )
  3743. {
  3744. ASSERT(NULL != psf2Cpanel);
  3745. ASSERT(NULL != pidlItem);
  3746. SHCOLUMNID scid = SCID_CONTROLPANELCATEGORY;
  3747. VARIANT var;
  3748. VariantInit(&var);
  3749. DWORD dwCategoryID = 0; // The default. 0 == "other CPLs" category
  3750. HRESULT hr = psf2Cpanel->GetDetailsEx(pidlItem, &scid, &var);
  3751. if (SUCCEEDED(hr))
  3752. {
  3753. dwCategoryID = var.lVal;
  3754. }
  3755. //
  3756. // -1 is a special category ID meaning "don't categorize".
  3757. //
  3758. if (DWORD(-1) != dwCategoryID)
  3759. {
  3760. IUICommand *pc;
  3761. hr = Create_CplUiCommandOnPidl(pidlItem, IID_IUICommand, (void **)&pc);
  3762. if (SUCCEEDED(hr))
  3763. {
  3764. if (-1 == m_rgCplApplets[dwCategoryID].Append(pc))
  3765. {
  3766. pc->Release();
  3767. hr = E_OUTOFMEMORY;
  3768. }
  3769. }
  3770. }
  3771. VariantClear(&var);
  3772. return THR(hr);
  3773. }
  3774. HRESULT
  3775. CPL::CplNamespace_CreateInstance(
  3776. IEnumIDList *penumIDs,
  3777. REFIID riid,
  3778. void **ppvOut
  3779. )
  3780. {
  3781. ASSERT(NULL != penumIDs);
  3782. ASSERT(NULL != ppvOut);
  3783. ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
  3784. HRESULT hr = CCplNamespace::CreateInstance(penumIDs, riid, ppvOut);
  3785. return THR(hr);
  3786. }
  3787. HRESULT
  3788. CPL::CplNamespace_GetCategoryAppletCount(
  3789. ICplNamespace *pns,
  3790. eCPCAT eCategory,
  3791. int *pcApplets
  3792. )
  3793. {
  3794. ASSERT(NULL != pns);
  3795. ASSERT(NULL != pcApplets);
  3796. ASSERT(!IsBadWritePtr(pcApplets, sizeof(*pcApplets)));
  3797. *pcApplets = 0;
  3798. ICplCategory *pCategory;
  3799. HRESULT hr = pns->GetCategory(eCategory, &pCategory);
  3800. if (SUCCEEDED(hr))
  3801. {
  3802. IEnumUICommand *peuic;
  3803. hr = pCategory->EnumCplApplets(&peuic);
  3804. if (SUCCEEDED(hr))
  3805. {
  3806. IUICommand *puic;
  3807. while(S_OK == (hr = peuic->Next(1, &puic, NULL)))
  3808. {
  3809. puic->Release();
  3810. (*pcApplets)++;
  3811. }
  3812. peuic->Release();
  3813. }
  3814. pCategory->Release();
  3815. }
  3816. return hr;
  3817. }
  3818. } // namespace CPL