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

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