|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 2000
//
// File: cpnamespc.cpp
//
// This is a rather large module but it's not all that difficult. The
// primary purpose is to provide the 'data' associated with the new
// 'categorized' Control Panel user interface. Therefore, the visual
// work is done in cpview.cpp and the data is provided by cpnamespc.cpp.
// Through the implementation of ICplNamespace, the 'view' object obtains
// it's display information. All of this 'namespace' information is
// defined and made accessible through this module.
//
// The 'namespace' can be broken down into these concepts:
//
// 1. Links - title, icon & infotip
// 2. Actions
// 3. Restrictions
//
// Each link has a title, icon, infotip and an associated action. The
// action is 'invoked' when the user selects the link in the user interface.
// Actions may optionally be associated with a 'restriction'. If a
// restriction is enforced (usually based on some system state) the
// link associated with the action that is associated with the restriction
// is not made available to the user interface. Using this indirection
// mechanism, any link related to a restricted action is not displayed.
//
// At first glance one might be concerned with the amount of global data
// used (and being initialized). Note however that all of the information
// is defined as constant such that it can be resolved at compile and link
// time. Several goals drove the design of this module:
//
// 1. Easy maintenance of Control Panel content. It must be easy
// to add/remove/modify links in the UI.
//
// 2. Fast initialization. Everything is defined as constant data.
//
// 3. Logical separation of links, actions and restrictions
// to facilitate the one-to-many and many-to-many relationships
// that might occur in the namespace.
//
// Following the namespace initialization code, the remainder of the
// module implements ICplNamespace to make the data available to the view
// in a COM-friendly way.
//
//--------------------------------------------------------------------------
#include "shellprv.h"
#include <cowsite.h>
#include <startids.h>
#include "cpviewp.h"
#include "cpaction.h"
#include "cpguids.h"
#include "cpnamespc.h"
#include "cpuiele.h"
#include "cputil.h"
#include "ids.h"
#include "securent.h"
#include "prop.h"
//
// These icons are currently all the same image.
// Use separate macro names in the code in case the designers
// decide to use different icons for one or more.
//
#define IDI_CPTASK_SEEALSO IDI_CPTASK_ASSISTANCE
#define IDI_CPTASK_TROUBLESHOOTER IDI_CPTASK_ASSISTANCE
#define IDI_CPTASK_HELPANDSUPPORT IDI_CPTASK_ASSISTANCE
#define IDI_CPTASK_LEARNABOUT IDI_CPTASK_ASSISTANCE
namespace CPL {
typedef CDpa<UNALIGNED ITEMIDLIST, CDpaDestroyer_ILFree<UNALIGNED ITEMIDLIST> > CDpaItemIDList; typedef CDpa<IUICommand, CDpaDestroyer_Release<IUICommand> > CDpaUiCommand;
//
// WebView info type enumeration.
//
enum eCPWVTYPE { eCPWVTYPE_CPANEL, // The 'Control Panel' item.
eCPWVTYPE_SEEALSO, // The 'See Also' list.
eCPWVTYPE_TROUBLESHOOT, // The 'Troubleshooters' list.
eCPWVTYPE_LEARNABOUT, // The 'Learn About' list.
eCPWVTYPE_NUMTYPES };
//
// Define the SCID identifying the control panel category.
//
DEFINE_SCID(SCID_CONTROLPANELCATEGORY, PSGUID_CONTROLPANEL, PID_CONTROLPANEL_CATEGORY);
//-----------------------------------------------------------------------------
// Resource source classes
//
// The purpose of this trivial class is to abstract away the implementation
// of obtaining a resource identifier. The reason for this comes from needing
// different text resources (i.e. infotips) for different retail SKUs.
// For example, on Personal SKU, the Users & Passwords applet provides the
// ability to associate a picture with a user's account. On Server, it
// does not. Therefore, the infotip on Personal can include text about
// the user's picture while on Server it cannot. By introducing this level
// of abstraction, we can provide resource information through a resource
// function that can select the appropriate resource at runtime. Most
// links will still use fixed resources but with this abstraction, the calling
// code is none the wiser.
//-----------------------------------------------------------------------------
//
// Resource source function must return an LPCWSTR for the resource.
//
typedef LPCWSTR (*PFNRESOURCE)(ICplNamespace *pns);
class IResSrc { public: virtual LPCWSTR GetResource(ICplNamespace *pns) const = 0; };
class CResSrcStatic : public IResSrc { public: CResSrcStatic(LPCWSTR pszResource) : m_pszResource(pszResource) { }
LPCWSTR GetResource(ICplNamespace *pns) const { UNREFERENCED_PARAMETER(pns); TraceMsg(TF_CPANEL, "CResSrc::GetResource - m_pszResource = 0x%08X", m_pszResource); return m_pszResource; }
private: const LPCWSTR m_pszResource; };
class CResSrcFunc : public IResSrc { public: CResSrcFunc(PFNRESOURCE pfnResource) : m_pfnResource(pfnResource) { }
LPCWSTR GetResource(ICplNamespace *pns) const { TraceMsg(TF_CPANEL, "CResSrcFunc::GetResource - m_pfnResource = 0x%08X", m_pfnResource); return (*m_pfnResource)(pns); }
private: const PFNRESOURCE m_pfnResource; };
//
// This resource type represents "no resource". It simply
// returns a NULL value when the resource is requested. Clients
// that call this must be ready to handle this NULL pointer
// value. It was originally created to handle the no-tooltip
// behavior of Learn-About links.
//
class CResSrcNone : public IResSrc { public: CResSrcNone(void) { }
LPCWSTR GetResource(ICplNamespace *pns) const { UNREFERENCED_PARAMETER(pns); return NULL; } };
// ----------------------------------------------------------------------------
// Information describing links.
// ----------------------------------------------------------------------------
//
//
// 'Link' descriptor.
//
struct CPLINK_DESC { const IResSrc *prsrcIcon; // Icon resource identifier
const IResSrc *prsrcName; // The link's title resource ID.
const IResSrc *prsrcInfotip; // The link's infotip resource ID.
const IAction *pAction; // The link's action when clicked.
};
//
// Set of 'support' links.
//
struct CPLINK_SUPPORT { const CPLINK_DESC **ppSeeAlsoLinks; // 'See Also' links for the category.
const CPLINK_DESC **ppTroubleshootLinks; // 'Troubleshoot' links for the category.
const CPLINK_DESC **ppLearnAboutLinks; // 'Learn About' links for the category.
};
//
// 'Category' descriptor. One defined for each category.
//
struct CPCAT_DESC { eCPCAT idCategory; // The category's ID.
LPCWSTR pszHelpSelection; // Selection part of HSS help URL.
const CPLINK_DESC *pLink; // The category's display info and action
const CPLINK_DESC **ppTaskLinks; // The category's task list.
CPLINK_SUPPORT slinks; // Support links.
};
// ----------------------------------------------------------------------------
// Restrictions
//
// Restrictions are an important part of the control panel display logic.
// Each link element in the UI can be restricted from view based on one or
// more system conditions at the time of display. To ensure the correct
// logic is used, it is critical to have a method of describing these restrictions
// that is easily readable and verifiable against a specification. Testing
// all of the possible scenarios is a difficult task, therefore the code must
// be written in a manner conducive to finding errors by inspection as well.
// This means, keep it simple. Each link action object can be optionally associated
// with a 'restriction' object. Restriction objects implement CPL::IRestrict.
// The most common restriction object CRestrictFunc simply calls a function
// provided to the object's constructor. The function is called when the
// restriction status (restricted/allowed) is desired. There is also
// class CRestrictApplet for tasks who's presence is directly linked to
// the presence/restriction of a particular CPL applet based on policy alone.
//
// Since there may be many task links on a given Control Panel page that
// means there will be multiple restriction expressions evaluated each
// time the page is displayed. Often the expressions across a set of
// actions are evaluating many of the same terms. Some of these terms require
// registry lookups. To help performance, a simple caching mechanism
// has been introduced into the 'namespace' object. Each restriction function
// is passed a pointer to the current 'namespace' object. As the namespace
// object remains alive the entire time the page is being constructed, it
// is an appropriate place to cache frequently used data. You'll see
// many instances below where the namespace object is queried for restriction
// data. The members of the namespace object associated with this restriction
// data are of type CTriState. This simple class implements the concept of
// an 'uninitialized boolean' value, allowing the code to determine if a given
// boolean member has yet to be initialized with a valid boolean value. If
// the namespace is asked for the value of one of these tri-state booleans
// and that member has not yet been initialized, the namespace calls the
// appropriate system functions and initializes the boolean value. From that
// time forward, the member's value is returned immediately. This ensures that
// for any given restriction term, we do the expensive stuff only once.
// Being an on-demand mechanism, we also gather only the information that is
// needed.
//
// [brianau - 03/18/01]
//
HRESULT Restrict32CtrlPanel(ICplNamespace *pns) { HRESULT hr = S_FALSE; #if !defined(_WIN64)
hr = S_OK; // restricted.
#endif
return hr; }
HRESULT RestrictAlways(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); return S_OK; // Always restricted.
}
HRESULT RestrictDisplayCpl(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowDeskCpl()) { hr = S_OK; } return hr; }
HRESULT RestrictThemes(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowDeskCpl() || SHRestricted(REST_NOTHEMESTAB) || SHRestricted(REST_NODISPLAYAPPEARANCEPAGE)) { hr = S_OK; } return hr; }
HRESULT RestrictWallpaper(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowDeskCpl() || SHRestricted(REST_NOCHANGINGWALLPAPER) || !pns->AllowDeskCplTab_Background()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictScreenSaver(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowDeskCpl() || !pns->AllowDeskCplTab_Screensaver()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictResolution(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowDeskCpl() || !pns->AllowDeskCplTab_Settings()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictAddPrinter(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE; if (SHRestricted(REST_NOPRINTERADD) || !IsAppletEnabled(NULL, MAKEINTRESOURCEW(IDS_PRNANDFAXFOLDER))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictRemoteDesktop(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->IsUserAdmin() || // Admins only.
pns->IsPersonal() || // Not available on personal.
!IsAppletEnabled(L"sysdm.cpl", MAKEINTRESOURCEW(IDS_CPL_SYSTEM))) // Respect sysdm.cpl policy.
{ hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictHomeNetwork(ICplNamespace *pns) { HRESULT hr = S_FALSE;
if (!pns->IsX86() || // x86 only.
pns->IsOnDomain() || // Not available on domains.
pns->IsServer() || // Not available on server.
!pns->IsUserAdmin() || // Admins only.
!IsAppletEnabled(L"hnetwiz.dll", NULL)) // Respect hnetwiz.dll policy.
{ hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictTsNetworking(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Available on personal and professional only.
//
if (!(pns->IsPersonal() || pns->IsProfessional())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictTsInetExplorer(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Available on personal and professional only.
//
if (!(pns->IsPersonal() || pns->IsProfessional())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictTsModem(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Available on server only.
//
if (!pns->IsServer()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictTsSharing(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Available on server only.
//
if (!pns->IsServer()) { hr = S_OK; // restricted.
} return hr; }
bool ShellKeyExists(SHELLKEY skey, LPCWSTR pszRegName) { TCHAR szValue[MAX_PATH];
DWORD cbValue = sizeof(szValue); return SUCCEEDED(SKGetValue(skey, pszRegName, NULL, NULL, szValue, &cbValue)); }
HRESULT RestrictBackupData(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Not available if the 'backuppath' shell key is missing.
// This logic is the same as that used by the "Tools" page
// in a volume property sheet.
//
if (!ShellKeyExists(SHELLKEY_HKLM_EXPLORER, TEXT("MyComputer\\BackupPath"))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictDefrag(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE; //
// Not available if the 'defragpath' shell key is missing.
// This logic is the same as that used by the "Tools" page
// in a volume property sheet.
//
if (!ShellKeyExists(SHELLKEY_HKLM_EXPLORER, TEXT("MyComputer\\DefragPath"))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictCleanUpDisk(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Not available if the 'cleanuppath' shell key is missing.
//
if (!ShellKeyExists(SHELLKEY_HKLM_EXPLORER, TEXT("MyComputer\\CleanupPath"))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictSystemRestore(ICplNamespace *pns) { HRESULT hr = S_FALSE; //
// Available only on x86.
//
if (!pns->IsX86() || pns->IsServer() || CPL::IsSystemRestoreRestricted()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictServerUserManager(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || pns->UsePersonalUserManager()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictFolderOptions(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE; if (SHRestricted(REST_NOFOLDEROPTIONS) || !IsAppletEnabled(NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_NS_FOLDEROPTIONS))) { hr = S_OK; } return hr; }
HRESULT RestrictIfNoAppletsInCplCategory(ICplNamespace *pns, eCPCAT eCategory) { int cCplApplets = 0; HRESULT hr = THR(CplNamespace_GetCategoryAppletCount(pns, eCategory, &cCplApplets)); if (SUCCEEDED(hr)) { if (0 == cCplApplets) { hr = S_OK; // 0 applets means we don't show the link.
} else { hr = S_FALSE; } } return hr; }
//
// If there are no CPL applets categorized under "Other",
// we hide the "Other CPL Options" link in the UI.
//
HRESULT RestrictOtherCplOptions(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!CPL::CategoryViewIsActive() || S_OK == RestrictIfNoAppletsInCplCategory(pns, eCPCAT_OTHER)) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictWindowsUpdate(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE; //
// First check the shell's restriction for the "Windows Update"
// item in the start menu. If the admin doesn't want access from
// the start menu, they most likely don't want it from Control Panel either.
//
if (SHRestricted(REST_NOUPDATEWINDOWS)) { hr = S_OK; } if (S_FALSE == hr) { //
// Not restricted in start menu.
// How about the global "Disable Windows Update" policy?
//
DWORD dwType; DWORD dwData; DWORD cbData = sizeof(dwData); if (ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\WindowsUpdate", L"DisableWindowsUpdateAccess", &dwType, &dwData, &cbData)) { if (REG_DWORD == dwType && 1 == dwData) { hr = S_OK; // restricted.
} } } return hr; }
HRESULT RestrictAddLanguage(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->IsUserAdmin() || !IsAppletEnabled(L"intl.cpl", MAKEINTRESOURCEW(IDS_CPL_REGIONALOPTIONS))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictAccountsCreate(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager() || !(pns->IsUserOwner() || pns->IsUserStandard())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictAccountsCreate2(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || pns->UsePersonalUserManager() || !(pns->IsUserOwner() || pns->IsUserStandard())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictAccountsChange(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager() || !(pns->IsUserOwner() || pns->IsUserStandard())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictAccountsPicture(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictLearnAboutAccounts(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager()) { hr = S_OK; } return hr; }
HRESULT RestrictLearnAboutAccountTypes(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager() || !IsUserAdmin()) // topic is for non-admins only.
{ hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictLearnAboutChangeName(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager() || !(pns->IsUserLimited() || pns->IsUserGuest())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictLearnAboutCreateAccount(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager() || !(pns->IsUserLimited() || pns->IsUserGuest())) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictLearnAboutFUS(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->AllowUserManager() || !pns->UsePersonalUserManager()) { hr = S_OK; } return hr; }
HRESULT RestrictHardwareWizard(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->IsUserAdmin() || !IsAppletEnabled(L"hdwwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDHARDWARE))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictVpnConnections(ICplNamespace *pns) { HRESULT hr = S_FALSE; if (!pns->IsUserAdmin()) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictArp(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE;
//
// Why we don't check SHRestricted(REST_ARP_NOARP)?
//
// 1. We don't hide category links for any reason.
// 2. If that policy is enabled and appwiz.cpl is allowed,
// (remember, those are different policies)
// we'll display the ARP category page and it will still
// show the ARP applet icon. Since there is at least one
// task link or icon, we don't display the "content disabled
// by your admin" barricade. Then the user will click on the
// applet icon and get ARP's "I've been disabled" messagebox.
//
// By not checking this policy, clicking on the category link
// will invoke ARP and ARP will display it's message.
// I think this is a better user experience.
//
if (!IsAppletEnabled(L"appwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDREMOVEPROGRAMS))) { hr = S_OK; // restricted.
} return hr; }
//
// The ARP category (and it's tasks) are displayed only when there
// are 2+ applets registered for that category (ARP and one or more
// other applets). Unlike RestrictArp() above, we DO want to consider
// SHRestricted(REST_ARP_NOARP). This way if ARP is restricted in
// ANY way, it's related tasks will not appear.
//
HRESULT RestrictArpAddProgram(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE;
if (SHRestricted(REST_ARP_NOARP) || SHRestricted(REST_ARP_NOADDPAGE) || !IsAppletEnabled(L"appwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDREMOVEPROGRAMS))) { hr = S_OK; // restricted.
} return hr; }
HRESULT RestrictArpRemoveProgram(ICplNamespace *pns) { UNREFERENCED_PARAMETER(pns); HRESULT hr = S_FALSE;
if (SHRestricted(REST_ARP_NOARP) || SHRestricted(REST_ARP_NOREMOVEPAGE) || !IsAppletEnabled(L"appwiz.cpl", MAKEINTRESOURCEW(IDS_CPL_ADDREMOVEPROGRAMS))) { hr = S_OK; // restricted.
} return hr; }
//-----------------------------------------------------------------------------
// Restriction objects (alphabetical order please)
//-----------------------------------------------------------------------------
//
// To restrict an action, create a restriction object and associate it with the
// action in the Action object declarations below.
//
const CRestrictFunc g_Restrict32CtrlPanel (Restrict32CtrlPanel); const CRestrictApplet g_RestrictAccessibility (L"access.cpl", MAKEINTRESOURCEW(IDS_CPL_ACCESSIBILITYOPTIONS)); const CRestrictApplet g_RestrictAccessWizard (L"accwiz.exe", NULL); const CRestrictFunc g_RestrictAccountsCreate (RestrictAccountsCreate); const CRestrictFunc g_RestrictAccountsCreate2 (RestrictAccountsCreate2); const CRestrictFunc g_RestrictAccountsChange (RestrictAccountsChange); const CRestrictFunc g_RestrictAccountsPicture (RestrictAccountsPicture); const CRestrictFunc g_RestrictAccountsServer (RestrictServerUserManager); const CRestrictFunc g_RestrictAddLanguage (RestrictAddLanguage); const CRestrictFunc g_RestrictAddPrinter (RestrictAddPrinter); const CRestrictApplet g_RestrictAdminTools (NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_NS_ADMIN_TOOLS)); const CRestrictFunc g_RestrictAlways (RestrictAlways); const CRestrictFunc g_RestrictArp (RestrictArp); const CRestrictFunc g_RestrictArpAddProgram (RestrictArpAddProgram); const CRestrictFunc g_RestrictArpRemoveProgram (RestrictArpRemoveProgram); const CRestrictFunc g_RestrictBackupData (RestrictBackupData); const CRestrictFunc g_RestrictCleanUpDisk (RestrictCleanUpDisk); const CRestrictApplet g_RestrictDateTime (L"timedate.cpl", MAKEINTRESOURCEW(IDS_CPL_DATETIME)); const CRestrictFunc g_RestrictDefrag (RestrictDefrag); const CRestrictFunc g_RestrictDisplayCpl (RestrictDisplayCpl); const CRestrictFunc g_RestrictFolderOptions (RestrictFolderOptions); const CRestrictApplet g_RestrictFontsFolder (NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_NS_FONTS)); const CRestrictFunc g_RestrictHomeNetwork (RestrictHomeNetwork); const CRestrictFunc g_RestrictHardwareWizard (RestrictHardwareWizard); const CRestrictApplet g_RestrictInternational (L"intl.cpl", MAKEINTRESOURCEW(IDS_CPL_REGIONALOPTIONS)); const CRestrictFunc g_RestrictLearnAboutAccounts (RestrictLearnAboutAccounts); const CRestrictFunc g_RestrictLearnAboutAccountTypes (RestrictLearnAboutAccountTypes); const CRestrictFunc g_RestrictLearnAboutChangeName (RestrictLearnAboutChangeName); const CRestrictFunc g_RestrictLearnAboutCreateAccount(RestrictLearnAboutCreateAccount); const CRestrictFunc g_RestrictLearnAboutFUS (RestrictLearnAboutFUS); const CRestrictApplet g_RestrictMousePointers (L"main.cpl", MAKEINTRESOURCEW(IDS_CPL_MOUSE)); const CRestrictApplet g_RestrictNetConnections (L"inetcpl.cpl", MAKEINTRESOURCEW(IDS_CPL_INTERNETOPTIONS)); const CRestrictFunc g_RestrictOtherCplOptions (RestrictOtherCplOptions); const CRestrictApplet g_RestrictPhoneModemCpl (L"telephon.cpl", MAKEINTRESOURCEW(IDS_CPL_PHONEANDMODEMOPTIONS)); const CRestrictApplet g_RestrictPowerOptions (L"powercfg.cpl", MAKEINTRESOURCEW(IDS_CPL_POWEROPTIONS)); const CRestrictApplet g_RestrictPrinters (NULL, MAKEINTRESOURCEW(IDS_PRNANDFAXFOLDER)); const CRestrictFunc g_RestrictRemoteDesktop (RestrictRemoteDesktop); const CRestrictFunc g_RestrictResolution (RestrictResolution); const CRestrictApplet g_RestrictScannersCameras (NULL, MAKEINTRESOURCEW(IDS_CPL_SCANNERSANDCAMERAS)); const CRestrictFunc g_RestrictScreenSaver (RestrictScreenSaver); const CRestrictApplet g_RestrictScheduledTasks (NULL, MAKEINTRESOURCEW(IDS_LOCALGDN_LNK_SCHEDULED_TASKS)); const CRestrictApplet g_RestrictSounds (L"mmsys.cpl", MAKEINTRESOURCEW(IDS_CPL_SOUNDSANDAUDIO)); const CRestrictApplet g_RestrictSystemCpl (L"sysdm.cpl", MAKEINTRESOURCEW(IDS_CPL_SYSTEM)); const CRestrictFunc g_RestrictSystemRestore (RestrictSystemRestore); const CRestrictApplet g_RestrictTaskbarProps (NULL, MAKEINTRESOURCEW(IDS_CP_TASKBARANDSTARTMENU)); const CRestrictFunc g_RestrictThemes (RestrictThemes); const CRestrictFunc g_RestrictTsModem (RestrictTsModem); const CRestrictFunc g_RestrictTsInetExplorer (RestrictTsInetExplorer); const CRestrictFunc g_RestrictTsNetworking (RestrictTsNetworking); const CRestrictFunc g_RestrictTsSharing (RestrictTsSharing); const CRestrictApplet g_RestrictUserManager (L"nusrmgr.cpl", MAKEINTRESOURCEW(IDS_CPL_USERACCOUNTS)); const CRestrictFunc g_RestrictVpnConnections (RestrictVpnConnections); const CRestrictFunc g_RestrictWallpaper (RestrictWallpaper); const CRestrictFunc g_RestrictWindowsUpdate (RestrictWindowsUpdate);
//-----------------------------------------------------------------------------
// Resource functions
//-----------------------------------------------------------------------------
//
// The tooltip for the accounts manager varies based upon the capabilities
// of the application used. On Personal we provide the ability to associate
// a user's picture with their account. The tooltip mentions this. On server
// this capability is not present. Therefore, the tooltip must not mention
// this.
//
LPCWSTR GetCatAccountsInfotip(ICplNamespace *pns) { if (pns->AllowUserManager() && pns->UsePersonalUserManager()) { return MAKEINTRESOURCEW(IDS_CPCAT_ACCOUNTS_INFOTIP); } else { //
// Personal user manager is restricted. Display the
// infotip without the term "picture".
//
return MAKEINTRESOURCEW(IDS_CPCAT_ACCOUNTS_INFOTIP2); } }
LPCWSTR GetAccountsInfotip(ICplNamespace *pns) { if (pns->AllowUserManager() && pns->UsePersonalUserManager()) { return MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_INFOTIP); } else { //
// Personal user manager is restricted. Display the
// infotip without the term "picture".
//
return MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_INFOTIP2); } }
LPCWSTR GetTsNetworkTitle(ICplNamespace *pns) { if ((pns->IsPersonal() || pns->IsProfessional()) && !pns->IsOnDomain()) { return MAKEINTRESOURCE(IDS_CPTASK_TSHOMENETWORKING_TITLE); } else { return MAKEINTRESOURCE(IDS_CPTASK_TSNETWORK_TITLE); } }
//-----------------------------------------------------------------------------
// Action objects (alphabetical order please)
//-----------------------------------------------------------------------------
//
// Each object represents some action taken when a link in Control Panel is
// selected. Actions are associated with links in the g_Link_XXXX declarations below.
//
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); const CShellExecuteSysDir g_LinkAction_AccessWizard (L"accwiz.exe", NULL, &g_RestrictAccessWizard); const COpenUserMgrApplet g_LinkAction_Accounts (&g_RestrictUserManager); const COpenCplAppletSysDir g_LinkAction_AccountsChange (L"nusrmgr.cpl ,initialTask=ChangeAccount", &g_RestrictAccountsChange); const COpenCplAppletSysDir g_LinkAction_AccountsCreate (L"nusrmgr.cpl ,initialTask=CreateAccount", &g_RestrictAccountsCreate); const COpenCplAppletSysDir g_LinkAction_AccountsCreate2 (L"nusrmgr.cpl", &g_RestrictAccountsCreate2); const COpenCplAppletSysDir g_LinkAction_AccountsPict (L"nusrmgr.cpl ,initialTask=ChangePicture", &g_RestrictAccountsPicture); const CAddPrinter g_LinkAction_AddPrinter (&g_RestrictAddPrinter); const COpenCplAppletSysDir g_LinkAction_AddProgram (L"appwiz.cpl ,1", &g_RestrictArpAddProgram); const COpenCplAppletSysDir g_LinkAction_Arp (L"appwiz.cpl", &g_RestrictArp); const COpenCplAppletSysDir g_LinkAction_AutoUpdate (L"sysdm.cpl ,@wuaueng.dll,10000", &g_RestrictSystemCpl); const CExecDiskUtil g_LinkAction_BackupData (eDISKUTIL_BACKUP, &g_RestrictBackupData); const COpenCplCategory g_LinkAction_CatAccessibility (eCPCAT_ACCESSIBILITY); const COpenCplCategory2 g_LinkAction_CatAccounts (eCPCAT_ACCOUNTS, &g_LinkAction_Accounts); const COpenCplCategory g_LinkAction_CatAppearance (eCPCAT_APPEARANCE); const COpenCplCategory2 g_LinkAction_CatArp (eCPCAT_ARP, &g_LinkAction_Arp); const COpenCplCategory g_LinkAction_CatHardware (eCPCAT_HARDWARE); const COpenCplCategory g_LinkAction_CatNetwork (eCPCAT_NETWORK); const COpenCplCategory g_LinkAction_CatOther (eCPCAT_OTHER, &g_RestrictAlways); const COpenCplCategory g_LinkAction_CatPerfMaint (eCPCAT_PERFMAINT); const COpenCplCategory g_LinkAction_CatRegional (eCPCAT_REGIONAL); const COpenCplCategory g_LinkAction_CatSound (eCPCAT_SOUND); const CExecDiskUtil g_LinkAction_CleanUpDisk (eDISKUTIL_CLEANUP, &g_RestrictCleanUpDisk); const COpenCplAppletSysDir g_LinkAction_DateTime (L"timedate.cpl", &g_RestrictDateTime); const CExecDiskUtil g_LinkAction_Defrag (eDISKUTIL_DEFRAG, &g_RestrictDefrag); const COpenCplAppletSysDir g_LinkAction_DisplayCpl (L"desk.cpl", &g_RestrictDisplayCpl); const COpenDeskCpl g_LinkAction_DisplayRes (CPLTAB_DESK_SETTINGS, &g_RestrictResolution); const COpenCplAppletSysDir g_LinkAction_DisplayTheme (L"desk.cpl", &g_RestrictThemes); const CRunDll32 g_LinkAction_FolderOptions (L"shell32.dll,Options_RunDLL 0", &g_RestrictFolderOptions); const CNavigateURL g_LinkAction_FontsFolder (L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}", &g_RestrictFontsFolder); const COpenCplAppletSysDir g_LinkAction_HardwareWizard (L"hdwwiz.cpl", &g_RestrictHardwareWizard); const CTrayCommand g_LinkAction_HelpAndSupport (IDM_HELPSEARCH); const COpenCplAppletSysDir g_LinkAction_HighContrast (L"access.cpl ,3", &g_RestrictAccessibility); const CRunDll32 g_LinkAction_HomeNetWizard (L"hnetwiz.dll,HomeNetWizardRunDll", &g_RestrictHomeNetwork); const CShellExecuteSysDir g_LinkAction_Magnifier (L"magnify.exe"); const COpenCplAppletSysDir g_LinkAction_Language (L"intl.cpl ,1", &g_RestrictAddLanguage); const CNavigateURL g_LinkAction_LearnAccounts (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpWindowsAccounts.htm", &g_RestrictLearnAboutAccounts); const CNavigateURL g_LinkAction_LearnAccountsTypes (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpAccountTypes.htm", &g_RestrictLearnAboutAccountTypes); const CNavigateURL g_LinkAction_LearnAccountsChangeName (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpChangeNonAdmin.htm", &g_RestrictLearnAboutChangeName); const CNavigateURL g_LinkAction_LearnAccountsCreate (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpCreateAccount.htm", &g_RestrictLearnAboutCreateAccount); const CNavigateURL g_LinkAction_LearnSwitchUsers (L"ms-its:%windir%\\help\\nusrmgr.chm::/HelpFUS.htm", &g_RestrictLearnAboutFUS); const COpenCplAppletSysDir g_LinkAction_MousePointers (L"main.cpl ,2", &g_RestrictMousePointers); const CNavigateURL g_LinkAction_MyComputer (L"shell:DriveFolder"); const CNavigateURL g_LinkAction_MyNetPlaces (L"shell:::{208D2C60-3AEA-1069-A2D7-08002B30309D}"); const COpenCplAppletSysDir g_LinkAction_NetConnections (L"inetcpl.cpl ,4", &g_RestrictNetConnections); const CActionNYI g_LinkAction_NotYetImpl (L"Under construction"); const CShellExecuteSysDir g_LinkAction_OnScreenKbd (L"osk.exe"); const COpenCplCategory g_LinkAction_OtherCplOptions (eCPCAT_OTHER, &g_RestrictOtherCplOptions); const COpenCplAppletSysDir g_LinkAction_PhoneModemCpl (L"telephon.cpl", &g_RestrictPhoneModemCpl); const COpenCplAppletSysDir g_LinkAction_PowerCpl (L"powercfg.cpl", &g_RestrictPowerOptions); const COpenCplAppletSysDir g_LinkAction_Region (L"intl.cpl", &g_RestrictInternational); const COpenCplAppletSysDir g_LinkAction_RemoteDesktop (L"sysdm.cpl ,@remotepg.dll,10000", &g_RestrictRemoteDesktop); const COpenCplAppletSysDir g_LinkAction_RemoveProgram (L"appwiz.cpl ,0", &g_RestrictArpRemoveProgram); const CNavigateURL g_LinkAction_ScheduledTasks (L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}", &g_RestrictScheduledTasks); const COpenDeskCpl g_LinkAction_ScreenSaver (CPLTAB_DESK_SCREENSAVER, &g_RestrictScreenSaver); const COpenCplAppletSysDir g_LinkAction_SoundAccessibility(L"access.cpl ,2", &g_RestrictAccessibility); const COpenCplCategory g_LinkAction_Sounds (eCPCAT_SOUND); const COpenCplAppletSysDir g_LinkAction_SoundSchemes (L"mmsys.cpl ,1", &g_RestrictSounds); const COpenCplAppletSysDir g_LinkAction_SoundVolume (L"mmsys.cpl ,0", &g_RestrictSounds); const CShellExecuteSysDir g_LinkAction_SoundVolumeAdv (L"sndvol32.exe", NULL, &g_RestrictSounds); const COpenCplView g_LinkAction_SwToClassicView (eCPVIEWTYPE_CLASSIC); const COpenCplView g_LinkAction_SwToCategoryView (eCPVIEWTYPE_CATEGORY); const COpenCplAppletSysDir g_LinkAction_SystemCpl (L"sysdm.cpl ,@sysdm.cpl,10000", &g_RestrictSystemCpl); const CShellExecuteSysDir g_LinkAction_SystemRestore (L"restore\\rstrui.exe", NULL, &g_RestrictSystemRestore); const COpenTroubleshooter g_LinkAction_TsDisplay (L"tsdisp.htm"); const COpenTroubleshooter g_LinkAction_TsDvd (L"ts_dvd.htm"); const COpenTroubleshooter g_LinkAction_TsHardware (L"tshardw.htm"); const COpenTroubleshooter g_LinkAction_TsInetExplorer (L"tsie.htm", &g_RestrictTsInetExplorer); const COpenTroubleshooter g_LinkAction_TsModem (L"tsmodem.htm", &g_RestrictTsModem); const COpenTroubleshooter g_LinkAction_TsNetwork (L"tshomenet.htm", &g_RestrictTsNetworking); const CNavigateURL g_LinkAction_TsNetDiags (L"hcp://system/netdiag/dglogs.htm"); const COpenTroubleshooter g_LinkAction_TsPrinting (L"tsprint.htm"); const COpenTroubleshooter g_LinkAction_TsSharing (L"tsnetwrk.htm", &g_RestrictTsSharing); const COpenTroubleshooter g_LinkAction_TsStartup (L"tsstartup.htm"); const COpenTroubleshooter g_LinkAction_TsSound (L"tssound.htm"); const CNavigateURL g_LinkAction_ViewPrinters (L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}", &g_RestrictPrinters); const COpenCplAppletSysDir g_LinkAction_VisualPerf (L"sysdm.cpl ,-1", &g_RestrictSystemCpl); const CRunDll32 g_LinkAction_VpnConnections (L"netshell.dll,StartNCW 21010", &g_RestrictVpnConnections); const COpenDeskCpl g_LinkAction_Wallpaper (CPLTAB_DESK_BACKGROUND, &g_RestrictWallpaper); const CNavigateURL g_LinkAction_WindowsUpdate (L"http://www.microsoft.com/isapi/redir.dll?prd=Win2000&ar=WinUpdate", &g_RestrictWindowsUpdate);
//-----------------------------------------------------------------------------
// Link object initialization data (alphabetical order please)
//-----------------------------------------------------------------------------
//
// Each g_Link_XXXX variable represents a link in the Control Panel namespace.
// Note that if a particular link is displayed in multiple places in the Control Panel,
// only one instance of a g_Link_XXXX variable is required.
//
// The 'S' and 'T' in g_SLink and g_TLink mean "Support" and "Task" respectively.
// I've used the generic term "support" to refer to items that appear in one
// of the webview lists in the left-hand pane.
// We may have a link in a support list and in a category task list that essentially
// do the same thing but they have different icons and titles. The 'S' and 'T'
// help differentiate.
//
const CResSrcStatic g_SLinkRes_32CtrlPanel_Icon(MAKEINTRESOURCEW(IDI_CPTASK_32CPLS)); const CResSrcStatic g_SLinkRes_32CtrlPanel_Title(MAKEINTRESOURCEW(IDS_CPTASK_32CPLS_TITLE)); const CResSrcStatic g_SLinkRes_32CtrlPanel_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_32CPLS_INFOTIP)); const CPLINK_DESC g_SLink_32CtrlPanel = { &g_SLinkRes_32CtrlPanel_Icon, &g_SLinkRes_32CtrlPanel_Title, &g_SLinkRes_32CtrlPanel_Infotip, &g_LinkAction_32CtrlPanel };
const CResSrcStatic g_TLinkRes_AccessWizard_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_AccessWizard_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCESSWIZARD_TITLE)); const CResSrcStatic g_TLinkRes_AccessWizard_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCESSWIZARD_INFOTIP)); const CPLINK_DESC g_TLink_AccessWizard = { &g_TLinkRes_AccessWizard_Icon, &g_TLinkRes_AccessWizard_Title, &g_TLinkRes_AccessWizard_Infotip, &g_LinkAction_AccessWizard };
const CResSrcStatic g_TLinkRes_AccountsChange_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_AccountsChange_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_TITLE)); const CResSrcFunc g_TLinkRes_AccountsChange_Infotip(GetAccountsInfotip); const CPLINK_DESC g_TLink_AccountsChange = { &g_TLinkRes_AccountsChange_Icon, &g_TLinkRes_AccountsChange_Title, &g_TLinkRes_AccountsChange_Infotip, &g_LinkAction_AccountsChange };
const CResSrcStatic g_TLinkRes_AccountsCreate_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_AccountsCreate_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSCREATE_TITLE)); const CResSrcStatic g_TLinkRes_AccountsCreate_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSCREATE_INFOTIP)); const CPLINK_DESC g_TLink_AccountsCreate = { &g_TLinkRes_AccountsCreate_Icon, &g_TLinkRes_AccountsCreate_Title, &g_TLinkRes_AccountsCreate_Infotip, &g_LinkAction_AccountsCreate };
//
// This link uses the same visual information as g_TLink_AccountsCreate above.
// The difference is in the action performed on selection.
//
const CPLINK_DESC g_TLink_AccountsCreate2 = { &g_TLinkRes_AccountsCreate_Icon, &g_TLinkRes_AccountsCreate_Title, &g_TLinkRes_AccountsCreate_Infotip, &g_LinkAction_AccountsCreate2 };
const CResSrcStatic g_SLinkRes_AccountsPict_Icon(L"nusrmgr.cpl,-205"); const CResSrcStatic g_SLinkRes_AccountsPict_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT_TITLE)); const CResSrcStatic g_SLinkRes_AccountsPict_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT_INFOTIP)); const CPLINK_DESC g_SLink_AccountsPict = { &g_SLinkRes_AccountsPict_Icon, &g_SLinkRes_AccountsPict_Title, &g_SLinkRes_AccountsPict_Infotip, &g_LinkAction_AccountsPict };
const CResSrcStatic g_TLinkRes_AccountsPict_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_AccountsPict_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT2_TITLE)); const CResSrcStatic g_TLinkRes_AccountsPict_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSPICT2_INFOTIP)); const CPLINK_DESC g_TLink_AccountsPict = { &g_TLinkRes_AccountsPict_Icon, &g_TLinkRes_AccountsPict_Title, &g_TLinkRes_AccountsPict_Infotip, &g_LinkAction_AccountsPict };
const CResSrcStatic g_TLinkRes_Accounts_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_Accounts_Title(MAKEINTRESOURCEW(IDS_CPTASK_ACCOUNTSMANAGE_TITLE)); const CResSrcFunc g_TLinkRes_Accounts_Infotip(GetAccountsInfotip); const CPLINK_DESC g_TLink_Accounts = { &g_TLinkRes_Accounts_Icon, &g_TLinkRes_Accounts_Title, &g_TLinkRes_Accounts_Infotip, &g_LinkAction_Accounts };
const CResSrcStatic g_TLinkRes_AddPrinter_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_AddPrinter_Title(MAKEINTRESOURCEW(IDS_CPTASK_ADDPRINTER_TITLE)); const CResSrcStatic g_TLinkRes_AddPrinter_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ADDPRINTER_INFOTIP)); const CPLINK_DESC g_TLink_AddPrinter = { &g_TLinkRes_AddPrinter_Icon, &g_TLinkRes_AddPrinter_Title, &g_TLinkRes_AddPrinter_Infotip, &g_LinkAction_AddPrinter };
const CResSrcStatic g_TLinkRes_AddProgram_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_AddProgram_Title(MAKEINTRESOURCEW(IDS_CPTASK_ADDPROGRAM_TITLE)); const CResSrcStatic g_TLinkRes_AddProgram_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ADDPROGRAM_INFOTIP)); const CPLINK_DESC g_TLink_AddProgram = { &g_TLinkRes_AddProgram_Icon, &g_TLinkRes_AddProgram_Title, &g_TLinkRes_AddProgram_Infotip, &g_LinkAction_AddProgram };
//
// Note that the "Auto Updates" icon is the same as the "Windows Update" icon.
// This is the way the Windows Update folks want it.
//
const CResSrcStatic g_SLinkRes_AutoUpdate_Icon(MAKEINTRESOURCEW(IDI_WINUPDATE)); const CResSrcStatic g_SLinkRes_AutoUpdate_Title(MAKEINTRESOURCEW(IDS_CPTASK_AUTOUPDATE_TITLE)); const CResSrcStatic g_SLinkRes_AutoUpdate_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_AUTOUPDATE_INFOTIP)); const CPLINK_DESC g_SLink_AutoUpdate = { &g_SLinkRes_AutoUpdate_Icon, &g_SLinkRes_AutoUpdate_Title, &g_SLinkRes_AutoUpdate_Infotip, &g_LinkAction_AutoUpdate };
const CResSrcStatic g_TLinkRes_BackupData_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_BackupData_Title(MAKEINTRESOURCEW(IDS_CPTASK_BACKUPDATA_TITLE)); const CResSrcStatic g_TLinkRes_BackupData_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_BACKUPDATA_INFOTIP)); const CPLINK_DESC g_TLink_BackupData = { &g_TLinkRes_BackupData_Icon, &g_TLinkRes_BackupData_Title, &g_TLinkRes_BackupData_Infotip, &g_LinkAction_BackupData };
const CResSrcStatic g_TLinkRes_CatAccessibility_Icon(MAKEINTRESOURCEW(IDI_CPCAT_ACCESSIBILITY)); const CResSrcStatic g_TLinkRes_CatAccessibility_Title(MAKEINTRESOURCEW(IDS_CPCAT_ACCESSIBILITY_TITLE)); const CResSrcStatic g_TLinkRes_CatAccessibility_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_ACCESSIBILITY_INFOTIP)); const CPLINK_DESC g_TLink_CatAccessibility = { &g_TLinkRes_CatAccessibility_Icon, &g_TLinkRes_CatAccessibility_Title, &g_TLinkRes_CatAccessibility_Infotip, &g_LinkAction_CatAccessibility };
const CResSrcStatic g_TLinkRes_CatAccounts_Icon(MAKEINTRESOURCEW(IDI_CPCAT_ACCOUNTS)); const CResSrcStatic g_TLinkRes_CatAccounts_Title(MAKEINTRESOURCEW(IDS_CPCAT_ACCOUNTS_TITLE)); const CResSrcFunc g_TLinkRes_CatAccounts_Infotip(GetCatAccountsInfotip); const CPLINK_DESC g_TLink_CatAccounts = { &g_TLinkRes_CatAccounts_Icon, &g_TLinkRes_CatAccounts_Title, &g_TLinkRes_CatAccounts_Infotip, &g_LinkAction_CatAccounts };
const CResSrcStatic g_TLinkRes_CatAppearance_Icon(MAKEINTRESOURCEW(IDI_CPCAT_APPEARANCE)); const CResSrcStatic g_TLinkRes_CatAppearance_Title(MAKEINTRESOURCEW(IDS_CPCAT_APPEARANCE_TITLE)); const CResSrcStatic g_TLinkRes_CatAppearance_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_APPEARANCE_INFOTIP)); const CPLINK_DESC g_TLink_CatAppearance = { &g_TLinkRes_CatAppearance_Icon, &g_TLinkRes_CatAppearance_Title, &g_TLinkRes_CatAppearance_Infotip, &g_LinkAction_CatAppearance };
const CResSrcStatic g_TLinkRes_CatArp_Icon(MAKEINTRESOURCEW(IDI_CPCAT_ARP)); const CResSrcStatic g_TLinkRes_CatArp_Title(MAKEINTRESOURCEW(IDS_CPCAT_ARP_TITLE)); const CResSrcStatic g_TLinkRes_CatArp_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_ARP_INFOTIP)); const CPLINK_DESC g_TLink_CatArp = { &g_TLinkRes_CatArp_Icon, &g_TLinkRes_CatArp_Title, &g_TLinkRes_CatArp_Infotip, &g_LinkAction_CatArp };
const CResSrcStatic g_TLinkRes_CatHardware_Icon(MAKEINTRESOURCEW(IDI_CPCAT_HARDWARE)); const CResSrcStatic g_TLinkRes_CatHardware_Title(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_TITLE)); const CResSrcStatic g_TLinkRes_CatHardware_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_INFOTIP)); const CPLINK_DESC g_TLink_CatHardware = { &g_TLinkRes_CatHardware_Icon, &g_TLinkRes_CatHardware_Title, &g_TLinkRes_CatHardware_Infotip, &g_LinkAction_CatHardware };
const CResSrcStatic g_TLinkRes_CatNetwork_Icon(MAKEINTRESOURCEW(IDI_CPCAT_NETWORK)); const CResSrcStatic g_TLinkRes_CatNetwork_Title(MAKEINTRESOURCEW(IDS_CPCAT_NETWORK_TITLE)); const CResSrcStatic g_TLinkRes_CatNetwork_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_NETWORK_INFOTIP)); const CPLINK_DESC g_TLink_CatNetwork = { &g_TLinkRes_CatNetwork_Icon, &g_TLinkRes_CatNetwork_Title, &g_TLinkRes_CatNetwork_Infotip, &g_LinkAction_CatNetwork };
const CResSrcStatic g_TLinkRes_CatOther_Icon(MAKEINTRESOURCEW(IDI_CPCAT_OTHERCPLS)); const CResSrcStatic g_TLinkRes_CatOther_Title(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_TITLE)); const CResSrcStatic g_TLinkRes_CatOther_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_INFOTIP)); const CPLINK_DESC g_TLink_CatOther = { &g_TLinkRes_CatOther_Icon, &g_TLinkRes_CatOther_Title, &g_TLinkRes_CatOther_Infotip, &g_LinkAction_CatOther };
const CResSrcStatic g_TLinkRes_CatPerfMaint_Icon(MAKEINTRESOURCEW(IDI_CPCAT_PERFMAINT)); const CResSrcStatic g_TLinkRes_CatPerfMaint_Title(MAKEINTRESOURCEW(IDS_CPCAT_PERFMAINT_TITLE)); const CResSrcStatic g_TLinkRes_CatPerfMaint_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_PERFMAINT_INFOTIP)); const CPLINK_DESC g_TLink_CatPerfMaint = { &g_TLinkRes_CatPerfMaint_Icon, &g_TLinkRes_CatPerfMaint_Title, &g_TLinkRes_CatPerfMaint_Infotip, &g_LinkAction_CatPerfMaint };
const CResSrcStatic g_TLinkRes_CatRegional_Icon(MAKEINTRESOURCEW(IDI_CPCAT_REGIONAL)); const CResSrcStatic g_TLinkRes_CatRegional_Title(MAKEINTRESOURCEW(IDS_CPCAT_REGIONAL_TITLE)); const CResSrcStatic g_TLinkRes_CatRegional_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_REGIONAL_INFOTIP)); const CPLINK_DESC g_TLink_CatRegional = { &g_TLinkRes_CatRegional_Icon, &g_TLinkRes_CatRegional_Title, &g_TLinkRes_CatRegional_Infotip, &g_LinkAction_CatRegional };
const CResSrcStatic g_TLinkRes_CatSound_Icon(MAKEINTRESOURCEW(IDI_CPCAT_SOUNDS)); const CResSrcStatic g_TLinkRes_CatSound_Title(MAKEINTRESOURCEW(IDS_CPCAT_SOUNDS_TITLE)); const CResSrcStatic g_TLinkRes_CatSound_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_SOUNDS_INFOTIP)); const CPLINK_DESC g_TLink_CatSound = { &g_TLinkRes_CatSound_Icon, &g_TLinkRes_CatSound_Title, &g_TLinkRes_CatSound_Infotip, &g_LinkAction_CatSound };
const CResSrcStatic g_TLinkRes_CleanUpDisk_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_CleanUpDisk_Title(MAKEINTRESOURCEW(IDS_CPTASK_CLEANUPDISK_TITLE)); const CResSrcStatic g_TLinkRes_CleanUpDisk_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_CLEANUPDISK_INFOTIP)); const CPLINK_DESC g_TLink_CleanUpDisk = { &g_TLinkRes_CleanUpDisk_Icon, &g_TLinkRes_CleanUpDisk_Title, &g_TLinkRes_CleanUpDisk_Infotip, &g_LinkAction_CleanUpDisk };
const CResSrcStatic g_TLinkRes_DateTime_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_DateTime_Title(MAKEINTRESOURCEW(IDS_CPTASK_DATETIME_TITLE)); const CResSrcStatic g_TLinkRes_DateTime_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_DATETIME_INFOTIP)); const CPLINK_DESC g_TLink_DateTime = { &g_TLinkRes_DateTime_Icon, &g_TLinkRes_DateTime_Title, &g_TLinkRes_DateTime_Infotip, &g_LinkAction_DateTime };
const CResSrcStatic g_TLinkRes_Defrag_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_Defrag_Title(MAKEINTRESOURCEW(IDS_CPTASK_DEFRAG_TITLE)); const CResSrcStatic g_TLinkRes_Defrag_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_DEFRAG_INFOTIP)); const CPLINK_DESC g_TLink_Defrag = { &g_TLinkRes_Defrag_Icon, &g_TLinkRes_Defrag_Title, &g_TLinkRes_Defrag_Infotip, &g_LinkAction_Defrag };
const CResSrcStatic g_SLinkRes_DisplayCpl_Icon(L"desk.cpl,0"); const CResSrcStatic g_SLinkRes_DisplayCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_DISPLAYCPL_TITLE)); const CResSrcStatic g_SLinkRes_DisplayCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_DISPLAYCPL_INFOTIP)); const CPLINK_DESC g_SLink_DisplayCpl = { &g_SLinkRes_DisplayCpl_Icon, &g_SLinkRes_DisplayCpl_Title, &g_SLinkRes_DisplayCpl_Infotip, &g_LinkAction_DisplayCpl };
const CResSrcStatic g_TLinkRes_DisplayRes_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_DisplayRes_Title(MAKEINTRESOURCEW(IDS_CPTASK_RESOLUTION_TITLE)); const CResSrcStatic g_TLinkRes_DisplayRes_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_RESOLUTION_INFOTIP)); const CPLINK_DESC g_TLink_DisplayRes = { &g_TLinkRes_DisplayRes_Icon, &g_TLinkRes_DisplayRes_Title, &g_TLinkRes_DisplayRes_Infotip, &g_LinkAction_DisplayRes };
const CResSrcStatic g_TLinkRes_DisplayTheme_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_DisplayTheme_Title(MAKEINTRESOURCEW(IDS_CPTASK_THEME_TITLE)); const CResSrcStatic g_TLinkRes_DisplayTheme_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_THEME_INFOTIP)); const CPLINK_DESC g_TLink_DisplayTheme = { &g_TLinkRes_DisplayTheme_Icon, &g_TLinkRes_DisplayTheme_Title, &g_TLinkRes_DisplayTheme_Infotip, &g_LinkAction_DisplayTheme };
const CResSrcStatic g_SLinkRes_FileTypes_Icon(MAKEINTRESOURCEW(IDI_FOLDEROPTIONS)); const CResSrcStatic g_SLinkRes_FileTypes_Title(MAKEINTRESOURCEW(IDS_CPTASK_FILETYPES_TITLE)); const CResSrcStatic g_SLinkRes_FileTypes_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_FILETYPES_INFOTIP)); const CPLINK_DESC g_SLink_FileTypes = { &g_SLinkRes_FileTypes_Icon, &g_SLinkRes_FileTypes_Title, &g_SLinkRes_FileTypes_Infotip, &g_LinkAction_FolderOptions };
const CResSrcStatic g_TLinkRes_FolderOptions_Icon(MAKEINTRESOURCEW(IDI_FOLDEROPTIONS)); const CResSrcStatic g_TLinkRes_FolderOptions_Title(MAKEINTRESOURCEW(IDS_CPTASK_FOLDEROPTIONS_TITLE)); const CResSrcStatic g_TLinkRes_FolderOptions_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_FOLDEROPTIONS_INFOTIP)); const CPLINK_DESC g_SLink_FolderOptions = { &g_TLinkRes_FolderOptions_Icon, &g_TLinkRes_FolderOptions_Title, &g_TLinkRes_FolderOptions_Infotip, &g_LinkAction_FolderOptions };
const CResSrcStatic g_SLinkRes_FontsFolder_Icon(MAKEINTRESOURCEW(IDI_STFONTS)); const CResSrcStatic g_SLinkRes_FontsFolder_Title(MAKEINTRESOURCEW(IDS_CPTASK_FONTS_TITLE)); const CResSrcStatic g_SLinkRes_FontsFolder_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_FONTS_INFOTIP)); const CPLINK_DESC g_SLink_FontsFolder = { &g_SLinkRes_FontsFolder_Icon, &g_SLinkRes_FontsFolder_Title, &g_SLinkRes_FontsFolder_Infotip, &g_LinkAction_FontsFolder };
const CResSrcStatic g_SLinkRes_Hardware_Icon(MAKEINTRESOURCEW(IDI_CPCAT_HARDWARE)); const CResSrcStatic g_SLinkRes_Hardware_Title(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_TITLE)); const CResSrcStatic g_SLinkRes_Hardware_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_HARDWARE_INFOTIP)); const CPLINK_DESC g_SLink_Hardware = { &g_SLinkRes_Hardware_Icon, &g_SLinkRes_Hardware_Title, &g_SLinkRes_Hardware_Infotip, &g_LinkAction_CatHardware };
const CResSrcStatic g_SLinkRes_HardwareWizard_Icon(L"hdwwiz.cpl,0"); const CResSrcStatic g_SLinkRes_HardwareWizard_Title(MAKEINTRESOURCEW(IDS_CPTASK_HARDWAREWIZ_TITLE)); const CResSrcStatic g_SLinkRes_HardwareWizard_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HARDWAREWIZ_INFOTIP)); const CPLINK_DESC g_SLink_HardwareWizard = { &g_SLinkRes_HardwareWizard_Icon, &g_SLinkRes_HardwareWizard_Title, &g_SLinkRes_HardwareWizard_Infotip, &g_LinkAction_HardwareWizard };
const CResSrcStatic g_SLinkRes_HelpAndSupport_Icon(MAKEINTRESOURCEW(IDI_STHELP)); const CResSrcStatic g_SLinkRes_HelpAndSupport_Title(MAKEINTRESOURCEW(IDS_CPTASK_HELPANDSUPPORT_TITLE)); const CResSrcStatic g_SLinkRes_HelpAndSupport_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HELPANDSUPPORT_INFOTIP)); const CPLINK_DESC g_SLink_HelpAndSupport = { &g_SLinkRes_HelpAndSupport_Icon, &g_SLinkRes_HelpAndSupport_Title, &g_SLinkRes_HelpAndSupport_Infotip, &g_LinkAction_HelpAndSupport };
const CResSrcStatic g_SLinkRes_HighContrast_Icon(MAKEINTRESOURCEW(IDI_CPTASK_HIGHCONTRAST)); const CResSrcStatic g_SLinkRes_HighContrast_Title(MAKEINTRESOURCEW(IDS_CPTASK_HIGHCONTRAST_TITLE)); const CResSrcStatic g_SLinkRes_HighContrast_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HIGHCONTRAST_INFOTIP)); const CPLINK_DESC g_SLink_HighContrast = { &g_SLinkRes_HighContrast_Icon, &g_SLinkRes_HighContrast_Title, &g_SLinkRes_HighContrast_Infotip, &g_LinkAction_HighContrast };
const CResSrcStatic g_TLinkRes_HighContrast_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_HighContrast_Title(MAKEINTRESOURCEW(IDS_CPTASK_TURNONHIGHCONTRAST_TITLE)); const CResSrcStatic g_TLinkRes_HighContrast_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TURNONHIGHCONTRAST_INFOTIP)); const CPLINK_DESC g_TLink_HighContrast = { &g_TLinkRes_HighContrast_Icon, &g_TLinkRes_HighContrast_Title, &g_TLinkRes_HighContrast_Infotip, &g_LinkAction_HighContrast };
const CResSrcStatic g_TLinkRes_HomeNetWizard_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_HomeNetWizard_Title(MAKEINTRESOURCEW(IDS_CPTASK_HOMENETWORK_TITLE)); const CResSrcStatic g_TLinkRes_HomeNetWizard_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_HOMENETWORK_INFOTIP)); const CPLINK_DESC g_TLink_HomeNetWizard = { &g_TLinkRes_HomeNetWizard_Icon, &g_TLinkRes_HomeNetWizard_Title, &g_TLinkRes_HomeNetWizard_Infotip, &g_LinkAction_HomeNetWizard };
const CResSrcStatic g_TLinkRes_Language_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_Language_Title(MAKEINTRESOURCEW(IDS_CPTASK_LANGUAGE_TITLE)); const CResSrcStatic g_TLinkRes_Language_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_LANGUAGE_INFOTIP)); const CPLINK_DESC g_TLink_Language = { &g_TLinkRes_Language_Icon, &g_TLinkRes_Language_Title, &g_TLinkRes_Language_Infotip, &g_LinkAction_Language };
//
// Learn-about topics use a standard icon and have no infotip.
//
const CResSrcStatic g_SLinkRes_LearnAbout_Icon(MAKEINTRESOURCE(IDI_CPTASK_LEARNABOUT)); const CResSrcNone g_SLinkRes_LearnAbout_Infotip;
const CResSrcStatic g_SLinkRes_LearnAccounts_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTS_TITLE)); const CPLINK_DESC g_SLink_LearnAccounts = { &g_SLinkRes_LearnAbout_Icon, &g_SLinkRes_LearnAccounts_Title, &g_SLinkRes_LearnAbout_Infotip, &g_LinkAction_LearnAccounts };
const CResSrcStatic g_SLinkRes_LearnAccountsTypes_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTSTYPES_TITLE)); const CPLINK_DESC g_SLink_LearnAccountsTypes = { &g_SLinkRes_LearnAbout_Icon, &g_SLinkRes_LearnAccountsTypes_Title, &g_SLinkRes_LearnAbout_Infotip, &g_LinkAction_LearnAccountsTypes };
const CResSrcStatic g_SLinkRes_LearnAccountsChangeName_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTSCHANGENAME_TITLE)); const CPLINK_DESC g_SLink_LearnAccountsChangeName = { &g_SLinkRes_LearnAbout_Icon, &g_SLinkRes_LearnAccountsChangeName_Title, &g_SLinkRes_LearnAbout_Infotip, &g_LinkAction_LearnAccountsChangeName };
const CResSrcStatic g_SLinkRes_LearnAccountsCreate_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNACCOUNTSCREATE_TITLE)); const CPLINK_DESC g_SLink_LearnAccountsCreate = { &g_SLinkRes_LearnAbout_Icon, &g_SLinkRes_LearnAccountsCreate_Title, &g_SLinkRes_LearnAbout_Infotip, &g_LinkAction_LearnAccountsCreate };
const CResSrcStatic g_SLinkRes_LearnSwitchUsers_Title(MAKEINTRESOURCE(IDS_CPTASK_LEARNSWITCHUSERS_TITLE)); const CPLINK_DESC g_SLink_LearnSwitchUsers = { &g_SLinkRes_LearnAbout_Icon, &g_SLinkRes_LearnSwitchUsers_Title, &g_SLinkRes_LearnAbout_Infotip, &g_LinkAction_LearnSwitchUsers };
const CResSrcStatic g_SLinkRes_Magnifier_Icon(MAKEINTRESOURCEW(IDI_CPTASK_MAGNIFIER)); const CResSrcStatic g_SLinkRes_Magnifier_Title(MAKEINTRESOURCEW(IDS_CPTASK_MAGNIFIER_TITLE)); const CResSrcStatic g_SLinkRes_Magnifier_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MAGNIFIER_INFOTIP)); const CPLINK_DESC g_SLink_Magnifier = { &g_SLinkRes_Magnifier_Icon, &g_SLinkRes_Magnifier_Title, &g_SLinkRes_Magnifier_Infotip, &g_LinkAction_Magnifier };
const CResSrcStatic g_SLinkRes_MousePointers_Icon(L"main.cpl,0"); const CResSrcStatic g_SLinkRes_MousePointers_Title(MAKEINTRESOURCEW(IDS_CPTASK_MOUSEPOINTERS_TITLE)); const CResSrcStatic g_SLinkRes_MousePointers_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MOUSEPOINTERS_INFOTIP)); const CPLINK_DESC g_SLink_MousePointers = { &g_SLinkRes_MousePointers_Icon, &g_SLinkRes_MousePointers_Title, &g_SLinkRes_MousePointers_Infotip, &g_LinkAction_MousePointers };
const CResSrcStatic g_SLinkRes_MyComputer_Icon(L"explorer.exe,0"); const CResSrcStatic g_SLinkRes_MyComputer_Title(MAKEINTRESOURCEW(IDS_CPTASK_MYCOMPUTER_TITLE)); const CResSrcStatic g_SLinkRes_MyComputer_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MYCOMPUTER_INFOTIP)); const CPLINK_DESC g_SLink_MyComputer = { &g_SLinkRes_MyComputer_Icon, &g_SLinkRes_MyComputer_Title, &g_SLinkRes_MyComputer_Infotip, &g_LinkAction_MyComputer };
const CResSrcStatic g_SLinkRes_MyNetPlaces_Icon(MAKEINTRESOURCEW(IDI_NETCONNECT)); const CResSrcStatic g_SLinkRes_MyNetPlaces_Title(MAKEINTRESOURCEW(IDS_CPTASK_MYNETPLACES_TITLE)); const CResSrcStatic g_SLinkRes_MyNetPlaces_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_MYNETPLACES_INFOTIP)); const CPLINK_DESC g_SLink_MyNetPlaces = { &g_SLinkRes_MyNetPlaces_Icon, &g_SLinkRes_MyNetPlaces_Title, &g_SLinkRes_MyNetPlaces_Infotip, &g_LinkAction_MyNetPlaces };
const CResSrcStatic g_TLinkRes_NetConnections_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_NetConnections_Title(MAKEINTRESOURCEW(IDS_CPTASK_NETCONNECTION_TITLE)); const CResSrcStatic g_TLinkRes_NetConnections_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_NETCONNECTION_INFOTIP)); const CPLINK_DESC g_TLink_NetConnections = { &g_TLinkRes_NetConnections_Icon, &g_TLinkRes_NetConnections_Title, &g_TLinkRes_NetConnections_Infotip, &g_LinkAction_NetConnections };
const CResSrcStatic g_SLinkRes_OnScreenKbd_Icon(MAKEINTRESOURCEW(IDI_CPTASK_ONSCREENKBD)); const CResSrcStatic g_SLinkRes_OnScreenKbd_Title(MAKEINTRESOURCEW(IDS_CPTASK_ONSCREENKBD_TITLE)); const CResSrcStatic g_SLinkRes_OnScreenKbd_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_ONSCREENKBD_INFOTIP)); const CPLINK_DESC g_SLink_OnScreenKbd = { &g_SLinkRes_OnScreenKbd_Icon, &g_SLinkRes_OnScreenKbd_Title, &g_SLinkRes_OnScreenKbd_Infotip, &g_LinkAction_OnScreenKbd };
const CResSrcStatic g_SLinkRes_OtherCplOptions_Icon(MAKEINTRESOURCEW(IDI_CPCAT_OTHERCPLS)); const CResSrcStatic g_SLinkRes_OtherCplOptions_Title(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_TITLE)); const CResSrcStatic g_SLinkRes_OtherCplOptions_Infotip(MAKEINTRESOURCEW(IDS_CPCAT_OTHERCPLS_INFOTIP)); const CPLINK_DESC g_SLink_OtherCplOptions = { &g_SLinkRes_OtherCplOptions_Icon, &g_SLinkRes_OtherCplOptions_Title, &g_SLinkRes_OtherCplOptions_Infotip, &g_LinkAction_OtherCplOptions };
const CResSrcStatic g_SLinkRes_PhoneModemCpl_Icon(L"telephon.cpl,0"); const CResSrcStatic g_SLinkRes_PhoneModemCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_PHONEMODEMCPL_TITLE)); const CResSrcStatic g_SLinkRes_PhoneModemCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_PHONEMODEMCPL_INFOTIP)); const CPLINK_DESC g_SLink_PhoneModemCpl = { &g_SLinkRes_PhoneModemCpl_Icon, &g_SLinkRes_PhoneModemCpl_Title, &g_SLinkRes_PhoneModemCpl_Infotip, &g_LinkAction_PhoneModemCpl };
const CResSrcStatic g_SLinkRes_PowerCpl_Icon(L"powercfg.cpl,-202"); const CResSrcStatic g_SLinkRes_PowerCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_POWERCPL_TITLE)); const CResSrcStatic g_SLinkRes_PowerCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_POWERCPL_INFOTIP)); const CPLINK_DESC g_SLink_PowerCpl = { &g_SLinkRes_PowerCpl_Icon, &g_SLinkRes_PowerCpl_Title, &g_SLinkRes_PowerCpl_Infotip, &g_LinkAction_PowerCpl };
const CResSrcStatic g_TLinkRes_Region_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_Region_Title(MAKEINTRESOURCEW(IDS_CPTASK_CHANGEREGION_TITLE)); const CResSrcStatic g_TLinkRes_Region_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_CHANGEREGION_INFOTIP)); const CPLINK_DESC g_TLink_Region = { &g_TLinkRes_Region_Icon, &g_TLinkRes_Region_Title, &g_TLinkRes_Region_Infotip, &g_LinkAction_Region };
const CResSrcStatic g_SLinkRes_RemoteDesktop_Icon(L"remotepg.dll,0"); const CResSrcStatic g_SLinkRes_RemoteDesktop_Title(MAKEINTRESOURCEW(IDS_CPTASK_REMOTEDESKTOP_TITLE)); const CResSrcStatic g_SLinkRes_RemoteDesktop_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_REMOTEDESKTOP_INFOTIP)); const CPLINK_DESC g_SLink_RemoteDesktop = { &g_SLinkRes_RemoteDesktop_Icon, &g_SLinkRes_RemoteDesktop_Title, &g_SLinkRes_RemoteDesktop_Infotip, &g_LinkAction_RemoteDesktop };
const CResSrcStatic g_TLinkRes_RemoveProgram_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_RemoveProgram_Title(MAKEINTRESOURCEW(IDS_CPTASK_REMOVEPROGRAM_TITLE)); const CResSrcStatic g_TLinkRes_RemoveProgram_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_REMOVEPROGRAM_INFOTIP)); const CPLINK_DESC g_TLink_RemoveProgram = { &g_TLinkRes_RemoveProgram_Icon, &g_TLinkRes_RemoveProgram_Title, &g_TLinkRes_RemoveProgram_Infotip, &g_LinkAction_RemoveProgram };
const CResSrcStatic g_TLinkRes_ScreenSaver_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_ScreenSaver_Title(MAKEINTRESOURCE(IDS_CPTASK_SCREENSAVER_TITLE)); const CResSrcStatic g_TLinkRes_ScreenSaver_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SCREENSAVER_INFOTIP)); const CPLINK_DESC g_TLink_ScreenSaver = { &g_TLinkRes_ScreenSaver_Icon, &g_TLinkRes_ScreenSaver_Title, &g_TLinkRes_ScreenSaver_Infotip, &g_LinkAction_ScreenSaver };
const CResSrcStatic g_SLinkRes_ScheduledTasks_Icon(L"mstask.dll,-100"); const CResSrcStatic g_SLinkRes_ScheduledTasks_Title(MAKEINTRESOURCEW(IDS_CPTASK_SCHEDULEDTASKS_TITLE)); const CResSrcStatic g_SLinkRes_ScheduledTasks_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SCHEDULEDTASKS_INFOTIP)); const CPLINK_DESC g_SLink_ScheduledTasks = { &g_SLinkRes_ScheduledTasks_Icon, &g_SLinkRes_ScheduledTasks_Title, &g_SLinkRes_ScheduledTasks_Infotip, &g_LinkAction_ScheduledTasks };
const CResSrcStatic g_SLinkRes_Sounds_Icon(L"mmsys.cpl,0"); const CResSrcStatic g_SLinkRes_Sounds_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCPL_TITLE)); const CResSrcStatic g_SLinkRes_Sounds_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCPL_INFOTIP)); const CPLINK_DESC g_SLink_Sounds = { &g_SLinkRes_Sounds_Icon, &g_SLinkRes_Sounds_Title, &g_SLinkRes_Sounds_Infotip, &g_LinkAction_Sounds };
const CResSrcStatic g_SLinkRes_SoundAccessibility_Icon(L"mmsys.cpl,0"); const CResSrcStatic g_SLinkRes_SoundAccessibility_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDACCESSIBILITY_TITLE)); const CResSrcStatic g_SLinkRes_SoundAccessibility_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDACCESSIBILITY_INFOTIP)); const CPLINK_DESC g_SLink_SoundAccessibility = { &g_SLinkRes_SoundAccessibility_Icon, &g_SLinkRes_SoundAccessibility_Title, &g_SLinkRes_SoundAccessibility_Infotip, &g_LinkAction_SoundAccessibility };
const CResSrcStatic g_TLinkRes_SoundSchemes_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_SoundSchemes_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCHEMES_TITLE)); const CResSrcStatic g_TLinkRes_SoundSchemes_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDSCHEMES_INFOTIP)); const CPLINK_DESC g_TLink_SoundSchemes = { &g_TLinkRes_SoundSchemes_Icon, &g_TLinkRes_SoundSchemes_Title, &g_TLinkRes_SoundSchemes_Infotip, &g_LinkAction_SoundSchemes };
const CResSrcStatic g_TLinkRes_SoundVolume_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_SoundVolume_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUME_TITLE)); const CResSrcStatic g_TLinkRes_SoundVolume_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUME_INFOTIP)); const CPLINK_DESC g_TLink_SoundVolume = { &g_TLinkRes_SoundVolume_Icon, &g_TLinkRes_SoundVolume_Title, &g_TLinkRes_SoundVolume_Infotip, &g_LinkAction_SoundVolume };
const CResSrcStatic g_SLinkRes_SoundVolumeAdv_Icon(L"sndvol32.exe,-300"); const CResSrcStatic g_SLinkRes_SoundVolumeAdv_Title(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUMEADV_TITLE)); const CResSrcStatic g_SLinkRes_SoundVolumeAdv_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SOUNDVOLUMEADV_INFOTIP)); const CPLINK_DESC g_SLink_SoundVolumeAdv = { &g_SLinkRes_SoundVolumeAdv_Icon, &g_SLinkRes_SoundVolumeAdv_Title, &g_SLinkRes_SoundVolumeAdv_Infotip, &g_LinkAction_SoundVolumeAdv };
const CResSrcStatic g_TLinkRes_SpeakerSettings_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_SpeakerSettings_Title(MAKEINTRESOURCEW(IDS_CPTASK_SPEAKERSETTINGS_TITLE)); const CResSrcStatic g_TLinkRes_SpeakerSettings_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SPEAKERSETTINGS_INFOTIP)); const CPLINK_DESC g_TLink_SpeakerSettings = { &g_TLinkRes_SpeakerSettings_Icon, &g_TLinkRes_SpeakerSettings_Title, &g_TLinkRes_SpeakerSettings_Infotip, &g_LinkAction_SoundVolume };
const CResSrcStatic g_SLinkRes_SystemCpl_Icon(L"sysdm.cpl,0"); const CResSrcStatic g_SLinkRes_SystemCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_TITLE)); const CResSrcStatic g_SLinkRes_SystemCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_INFOTIP)); const CPLINK_DESC g_SLink_SystemCpl = { &g_SLinkRes_SystemCpl_Icon, &g_SLinkRes_SystemCpl_Title, &g_SLinkRes_SystemCpl_Infotip, &g_LinkAction_SystemCpl };
const CResSrcStatic g_TLinkRes_SystemCpl_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_SystemCpl_Title(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_TITLE2)); const CResSrcStatic g_TLinkRes_SystemCpl_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMCPL_INFOTIP2)); const CPLINK_DESC g_TLink_SystemCpl = { &g_TLinkRes_SystemCpl_Icon, &g_TLinkRes_SystemCpl_Title, &g_TLinkRes_SystemCpl_Infotip, &g_LinkAction_SystemCpl };
const CResSrcStatic g_SLinkRes_SystemRestore_Icon(L"%systemroot%\\system32\\restore\\rstrui.exe,0"); const CResSrcStatic g_SLinkRes_SystemRestore_Title(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMRESTORE_TITLE)); const CResSrcStatic g_SLinkRes_SystemRestore_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SYSTEMRESTORE_INFOTIP)); const CPLINK_DESC g_SLink_SystemRestore = { &g_SLinkRes_SystemRestore_Icon, &g_SLinkRes_SystemRestore_Title, &g_SLinkRes_SystemRestore_Infotip, &g_LinkAction_SystemRestore };
const CResSrcStatic g_SLinkRes_SwToCategoryView_Icon(MAKEINTRESOURCEW(IDI_CPLFLD)); const CResSrcStatic g_SLinkRes_SwToCategoryView_Title(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCATEGORYVIEW_TITLE)); const CResSrcStatic g_SLinkRes_SwToCategoryView_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCATEGORYVIEW_INFOTIP)); const CPLINK_DESC g_SLink_SwToCategoryView = { &g_SLinkRes_SwToCategoryView_Icon, &g_SLinkRes_SwToCategoryView_Title, &g_SLinkRes_SwToCategoryView_Infotip, &g_LinkAction_SwToCategoryView };
const CResSrcStatic g_SLinkRes_SwToClassicView_Icon(MAKEINTRESOURCEW(IDI_CPLFLD)); const CResSrcStatic g_SLinkRes_SwToClassicView_Title(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCLASSICVIEW_TITLE)); const CResSrcStatic g_SLinkRes_SwToClassicView_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_SWITCHTOCLASSICVIEW_INFOTIP)); const CPLINK_DESC g_SLink_SwToClassicView = { &g_SLinkRes_SwToClassicView_Icon, &g_SLinkRes_SwToClassicView_Title, &g_SLinkRes_SwToClassicView_Infotip, &g_LinkAction_SwToClassicView };
const CResSrcStatic g_SLinkRes_TsDisplay_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsDisplay_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSDISPLAY_TITLE)); const CResSrcStatic g_SLinkRes_TsDisplay_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSDISPLAY_INFOTIP)); const CPLINK_DESC g_SLink_TsDisplay = { &g_SLinkRes_TsDisplay_Icon, &g_SLinkRes_TsDisplay_Title, &g_SLinkRes_TsDisplay_Infotip, &g_LinkAction_TsDisplay };
const CResSrcStatic g_SLinkRes_TsDvd_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsDvd_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSDVD_TITLE)); const CResSrcStatic g_SLinkRes_TsDvd_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSDVD_INFOTIP)); const CPLINK_DESC g_SLink_TsDvd = { &g_SLinkRes_TsDvd_Icon, &g_SLinkRes_TsDvd_Title, &g_SLinkRes_TsDvd_Infotip, &g_LinkAction_TsDvd };
const CResSrcStatic g_SLinkRes_TsHardware_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsHardware_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSHARDWARE_TITLE)); const CResSrcStatic g_SLinkRes_TsHardware_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSHARDWARE_INFOTIP)); const CPLINK_DESC g_SLink_TsHardware = { &g_SLinkRes_TsHardware_Icon, &g_SLinkRes_TsHardware_Title, &g_SLinkRes_TsHardware_Infotip, &g_LinkAction_TsHardware };
const CResSrcStatic g_SLinkRes_TsInetExplorer_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsInetExplorer_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSINETEXPLORER_TITLE)); const CResSrcStatic g_SLinkRes_TsInetExplorer_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSINETEXPLORER_INFOTIP)); const CPLINK_DESC g_SLink_TsInetExplorer = { &g_SLinkRes_TsInetExplorer_Icon, &g_SLinkRes_TsInetExplorer_Title, &g_SLinkRes_TsInetExplorer_Infotip, &g_LinkAction_TsInetExplorer };
const CResSrcStatic g_SLinkRes_TsModem_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsModem_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSMODEM_TITLE)); const CResSrcStatic g_SLinkRes_TsModem_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSMODEM_INFOTIP)); const CPLINK_DESC g_SLink_TsModem = { &g_SLinkRes_TsModem_Icon, &g_SLinkRes_TsModem_Title, &g_SLinkRes_TsModem_Infotip, &g_LinkAction_TsModem };
const CResSrcStatic g_SLinkRes_TsNetDiags_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsNetDiags_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSNETDIAGS_TITLE)); const CResSrcStatic g_SLinkRes_TsNetDiags_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSNETDIAGS_INFOTIP)); const CPLINK_DESC g_SLink_TsNetDiags = { &g_SLinkRes_TsNetDiags_Icon, &g_SLinkRes_TsNetDiags_Title, &g_SLinkRes_TsNetDiags_Infotip, &g_LinkAction_TsNetDiags };
const CResSrcStatic g_SLinkRes_TsNetwork_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcFunc g_SLinkRes_TsNetwork_Title(GetTsNetworkTitle); const CResSrcStatic g_SLinkRes_TsNetwork_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSNETWORK_INFOTIP)); const CPLINK_DESC g_SLink_TsNetwork = { &g_SLinkRes_TsNetwork_Icon, &g_SLinkRes_TsNetwork_Title, &g_SLinkRes_TsNetwork_Infotip, &g_LinkAction_TsNetwork };
const CResSrcStatic g_SLinkRes_TsPrinting_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsPrinting_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSPRINTING_TITLE)); const CResSrcStatic g_SLinkRes_TsPrinting_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSPRINTING_INFOTIP)); const CPLINK_DESC g_SLink_TsPrinting = { &g_SLinkRes_TsPrinting_Icon, &g_SLinkRes_TsPrinting_Title, &g_SLinkRes_TsPrinting_Infotip, &g_LinkAction_TsPrinting };
const CResSrcStatic g_SLinkRes_TsSharing_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsSharing_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSFILESHARING_TITLE)); const CResSrcStatic g_SLinkRes_TsSharing_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSFILESHARING_INFOTIP)); const CPLINK_DESC g_SLink_TsSharing = { &g_SLinkRes_TsSharing_Icon, &g_SLinkRes_TsSharing_Title, &g_SLinkRes_TsSharing_Infotip, &g_LinkAction_TsSharing };
const CResSrcStatic g_SLinkRes_TsSound_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsSound_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSSOUND_TITLE)); const CResSrcStatic g_SLinkRes_TsSound_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSSOUND_INFOTIP)); const CPLINK_DESC g_SLink_TsSound = { &g_SLinkRes_TsSound_Icon, &g_SLinkRes_TsSound_Title, &g_SLinkRes_TsSound_Infotip, &g_LinkAction_TsSound };
const CResSrcStatic g_SLinkRes_TsStartup_Icon(MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER)); const CResSrcStatic g_SLinkRes_TsStartup_Title(MAKEINTRESOURCEW(IDS_CPTASK_TSSTARTUP_TITLE)); const CResSrcStatic g_SLinkRes_TsStartup_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_TSSTARTUP_INFOTIP)); const CPLINK_DESC g_SLink_TsStartup = { &g_SLinkRes_TsStartup_Icon, &g_SLinkRes_TsStartup_Title, &g_SLinkRes_TsStartup_Infotip, &g_LinkAction_TsStartup };
const CResSrcStatic g_TLinkRes_ViewPrinters_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_ViewPrinters_Title(MAKEINTRESOURCEW(IDS_CPTASK_VIEWPRINTERS_TITLE)); const CResSrcStatic g_TLinkRes_ViewPrinters_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_VIEWPRINTERS_INFOTIP)); const CPLINK_DESC g_TLink_ViewPrinters = { &g_TLinkRes_ViewPrinters_Icon, &g_TLinkRes_ViewPrinters_Title, &g_TLinkRes_ViewPrinters_Infotip, &g_LinkAction_ViewPrinters };
const CResSrcStatic g_TLinkRes_VisualPerf_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_VisualPerf_Title(MAKEINTRESOURCEW(IDS_CPTASK_VISUALPERF_TITLE)); const CResSrcStatic g_TLinkRes_VisualPerf_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_VISUALPERF_INFOTIP)); const CPLINK_DESC g_TLink_VisualPerf = { &g_TLinkRes_VisualPerf_Icon, &g_TLinkRes_VisualPerf_Title, &g_TLinkRes_VisualPerf_Infotip, &g_LinkAction_VisualPerf };
const CResSrcStatic g_TLinkRes_VpnConnections_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_VpnConnections_Title(MAKEINTRESOURCEW(IDS_CPTASK_VPNCONNECTION_TITLE)); const CResSrcStatic g_TLinkRes_VpnConnections_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_VPNCONNECTION_INFOTIP)); const CPLINK_DESC g_TLink_VpnConnections = { &g_TLinkRes_VpnConnections_Icon, &g_TLinkRes_VpnConnections_Title, &g_TLinkRes_VpnConnections_Infotip, &g_LinkAction_VpnConnections };
const CResSrcStatic g_TLinkRes_Wallpaper_Icon(MAKEINTRESOURCEW(IDI_CP_CATEGORYTASK)); const CResSrcStatic g_TLinkRes_Wallpaper_Title(MAKEINTRESOURCEW(IDS_CPTASK_WALLPAPER_TITLE)); const CResSrcStatic g_TLinkRes_Wallpaper_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_WALLPAPER_INFOTIP)); const CPLINK_DESC g_TLink_Wallpaper = { &g_TLinkRes_Wallpaper_Icon, &g_TLinkRes_Wallpaper_Title, &g_TLinkRes_Wallpaper_Infotip, &g_LinkAction_Wallpaper };
const CResSrcStatic g_SLinkRes_WindowsUpdate_Icon(MAKEINTRESOURCEW(IDI_WINUPDATE)); const CResSrcStatic g_SLinkRes_WindowsUpdate_Title(MAKEINTRESOURCEW(IDS_CPTASK_WINDOWSUPDATE_TITLE)); const CResSrcStatic g_SLinkRes_WindowsUpdate_Infotip(MAKEINTRESOURCEW(IDS_CPTASK_WINDOWSUPDATE_INFOTIP)); const CPLINK_DESC g_SLink_WindowsUpdate = { &g_SLinkRes_WindowsUpdate_Icon, &g_SLinkRes_WindowsUpdate_Title, &g_SLinkRes_WindowsUpdate_Infotip, &g_LinkAction_WindowsUpdate };
//-----------------------------------------------------------------------------
// View page definitions.
//-----------------------------------------------------------------------------
//
// Main Control Panel page.
//
const CPLINK_DESC *g_rgpLink_Cpl_SeeAlso[] = { &g_SLink_WindowsUpdate, &g_SLink_HelpAndSupport, &g_SLink_32CtrlPanel, &g_SLink_OtherCplOptions, NULL };
const CPLINK_DESC *g_rgpLink_Cpl_SwToClassicView[] = { &g_SLink_SwToClassicView, NULL };
const CPLINK_DESC *g_rgpLink_Cpl_SwToCategoryView[] = { &g_SLink_SwToCategoryView, NULL };
//
// Accounts category
//
const CPLINK_DESC *g_rgpLink_Accounts_Tasks[] = { &g_TLink_AccountsChange, &g_TLink_AccountsCreate, // Active on non-server SKU
&g_TLink_AccountsCreate2, // Active on server SKU
&g_TLink_AccountsPict, NULL };
const CPLINK_DESC *g_rgpLink_Accounts_SeeAlso[] = { &g_TLink_CatAppearance, NULL };
const CPLINK_DESC *g_rgpLink_Accounts_LearnAbout[] = { &g_SLink_LearnAccounts, &g_SLink_LearnAccountsTypes, &g_SLink_LearnAccountsChangeName, &g_SLink_LearnAccountsCreate, &g_SLink_LearnSwitchUsers, NULL };
const CPCAT_DESC g_Category_Accounts = { eCPCAT_ACCOUNTS, L"Security_and_User_Accounts", &g_TLink_CatAccounts, g_rgpLink_Accounts_Tasks, { g_rgpLink_Accounts_SeeAlso, NULL, g_rgpLink_Accounts_LearnAbout } };
//
// Accessibility category
//
const CPLINK_DESC *g_rgpLink_Accessibility_Tasks[] = { &g_TLink_HighContrast, &g_TLink_AccessWizard, NULL };
const CPLINK_DESC *g_rgpLink_Accessibility_SeeAlso[] = { &g_SLink_Magnifier, &g_SLink_OnScreenKbd, NULL };
const CPCAT_DESC g_Category_Accessibility = { eCPCAT_ACCESSIBILITY, L"Accessibility", &g_TLink_CatAccessibility, g_rgpLink_Accessibility_Tasks, { g_rgpLink_Accessibility_SeeAlso, NULL, NULL }, };
//
// Appearance category
//
const CPLINK_DESC *g_rgpLink_Appearance_Tasks[] = { &g_TLink_DisplayTheme, &g_TLink_Wallpaper, &g_TLink_ScreenSaver, &g_TLink_DisplayRes, NULL };
const CPLINK_DESC *g_rgpLink_Appearance_SeeAlso[] = { &g_SLink_FontsFolder, &g_SLink_MousePointers, &g_SLink_HighContrast, &g_SLink_AccountsPict, NULL };
const CPLINK_DESC *g_rgpLink_Appearance_Troubleshoot[] = { &g_SLink_TsDisplay, &g_SLink_TsSound, NULL };
const CPCAT_DESC g_Category_Appearance = { eCPCAT_APPEARANCE, L"Appearance_and_Themes", &g_TLink_CatAppearance, g_rgpLink_Appearance_Tasks, { g_rgpLink_Appearance_SeeAlso, g_rgpLink_Appearance_Troubleshoot, NULL } };
//
// Add/Remove Programs (aka ARP) category
//
const CPLINK_DESC *g_rgpLink_Arp_SeeAlso[] = { &g_SLink_WindowsUpdate, &g_SLink_AutoUpdate, NULL };
const CPLINK_DESC *g_rgpLink_Arp_Tasks[] = { &g_TLink_AddProgram, &g_TLink_RemoveProgram, NULL };
const CPCAT_DESC g_Category_Arp = { eCPCAT_ARP, L"Add_or_Remove_Programs", &g_TLink_CatArp, g_rgpLink_Arp_Tasks, { g_rgpLink_Arp_SeeAlso, NULL, NULL }, };
//
// Hardware category
//
const CPLINK_DESC *g_rgpLink_Hardware_Tasks[] = { &g_TLink_ViewPrinters, &g_TLink_AddPrinter, NULL };
const CPLINK_DESC *g_rgpLink_Hardware_SeeAlso[] = { &g_SLink_HardwareWizard, &g_SLink_DisplayCpl, &g_SLink_Sounds, &g_SLink_PowerCpl, &g_SLink_SystemCpl, NULL };
const CPLINK_DESC *g_rgpLink_Hardware_Troubleshoot[] = { &g_SLink_TsHardware, &g_SLink_TsPrinting, &g_SLink_TsNetwork, NULL };
const CPCAT_DESC g_Category_Hardware = { eCPCAT_HARDWARE, L"Printers_and_Other_Hardware", &g_TLink_CatHardware, g_rgpLink_Hardware_Tasks, { g_rgpLink_Hardware_SeeAlso, g_rgpLink_Hardware_Troubleshoot, NULL } };
//
// Network category
//
const CPLINK_DESC *g_rgpLink_Network_Tasks[] = { &g_TLink_NetConnections, &g_TLink_VpnConnections, &g_TLink_HomeNetWizard, NULL };
const CPLINK_DESC *g_rgpLink_Network_SeeAlso[] = { &g_SLink_MyNetPlaces, &g_SLink_Hardware, &g_SLink_RemoteDesktop, &g_SLink_PhoneModemCpl, NULL };
const CPLINK_DESC *g_rgpLink_Network_Troubleshoot[] = { &g_SLink_TsNetwork, // Pro/Personal only.
&g_SLink_TsInetExplorer, // Pro/Personal only.
&g_SLink_TsSharing, // Server only.
&g_SLink_TsModem, // Server only.
&g_SLink_TsNetDiags, // All SKUs.
NULL };
const CPCAT_DESC g_Category_Network = { eCPCAT_NETWORK, L"Network_Connections", &g_TLink_CatNetwork, g_rgpLink_Network_Tasks, { g_rgpLink_Network_SeeAlso, g_rgpLink_Network_Troubleshoot, NULL } };
//
// Other CPLs category
//
const CPLINK_DESC *g_rgpLink_Other_SeeAlso[] = { &g_SLink_WindowsUpdate, &g_SLink_HelpAndSupport, NULL };
const CPCAT_DESC g_Category_Other = { eCPCAT_OTHER, NULL, // "Other" uses std Control Panel help topic.
&g_TLink_CatOther, NULL, { g_rgpLink_Other_SeeAlso, NULL, NULL } };
//
// PerfMaint category
//
const CPLINK_DESC *g_rgpLink_PerfMaint_Tasks[] = { &g_TLink_SystemCpl, &g_TLink_VisualPerf, &g_TLink_CleanUpDisk, &g_TLink_BackupData, &g_TLink_Defrag, NULL };
const CPLINK_DESC *g_rgpLink_PerfMaint_SeeAlso[] = { &g_SLink_FileTypes, &g_SLink_SystemRestore, NULL };
const CPLINK_DESC *g_rgpLink_PerfMaint_Troubleshoot[] = { &g_SLink_TsStartup, NULL };
const CPCAT_DESC g_Category_PerfMaint = { eCPCAT_PERFMAINT, L"Performance_and_Maintenance", &g_TLink_CatPerfMaint, g_rgpLink_PerfMaint_Tasks, { g_rgpLink_PerfMaint_SeeAlso, g_rgpLink_PerfMaint_Troubleshoot, NULL }, };
//
// Regional category
//
const CPLINK_DESC *g_rgpLink_Regional_Tasks[] = { &g_TLink_DateTime, &g_TLink_Region, &g_TLink_Language, NULL };
const CPLINK_DESC *g_rgpLink_Regional_SeeAlso[] = { &g_SLink_ScheduledTasks, NULL };
const CPCAT_DESC g_Category_Regional = { eCPCAT_REGIONAL, L"Date__Time__Language_and_Regional_Settings", &g_TLink_CatRegional, g_rgpLink_Regional_Tasks, { g_rgpLink_Regional_SeeAlso, NULL, NULL }, };
//
// Sound category
//
const CPLINK_DESC *g_rgpLink_Sound_Tasks[] = { &g_TLink_SoundVolume, &g_TLink_SoundSchemes, &g_TLink_SpeakerSettings, NULL };
const CPLINK_DESC *g_rgpLink_Sound_SeeAlso[] = { &g_SLink_SoundAccessibility, &g_SLink_SoundVolumeAdv, NULL };
const CPLINK_DESC *g_rgpLink_Sound_Troubleshoot[] = { &g_SLink_TsSound, &g_SLink_TsDvd, NULL };
const CPCAT_DESC g_Category_Sound = { eCPCAT_SOUND, L"Sounds__Speech_and_Audio_Devices", &g_TLink_CatSound, g_rgpLink_Sound_Tasks, { g_rgpLink_Sound_SeeAlso, g_rgpLink_Sound_Troubleshoot, NULL } };
//
// ********* IMPORTANT **********
//
// The order of these entries MUST match up with the category ID
// values in the cCPCAT enumeration. These IDs also map directly
// to the SCID_CONTROLPANELCATEGORY value stored for each CPL
// applet in the registry.
//
// Code using a category ID will map directly to this array.
// Order of display in the Category selection view is handled
// by the function CCplView::_DisplayIndexToCategoryIndex in
// cpview.cpp.
//
const CPCAT_DESC *g_rgpCplCatInfo[] = { &g_Category_Other, &g_Category_Appearance, &g_Category_Hardware, &g_Category_Network, &g_Category_Sound, &g_Category_PerfMaint, &g_Category_Regional, &g_Category_Accessibility, &g_Category_Arp, &g_Category_Accounts, NULL, };
//-----------------------------------------------------------------------------
// Helper functions used in support of the namespace.
//-----------------------------------------------------------------------------
//
// Copy one DPA of IUICommand ptrs to another.
// Returns:
// S_OK - All items copied.
// Error - Something failed.
//
HRESULT CplNamespace_CopyCommandArray( const CDpaUiCommand& rgFrom, CDpaUiCommand *prgTo ) { ASSERT(NULL != prgTo); ASSERT(0 == prgTo->Count());
HRESULT hr = S_OK; const int cCommands = rgFrom.Count(); for (int i = 0; i < cCommands && SUCCEEDED(hr); i++) { IUICommand *pc = const_cast<IUICommand *>(rgFrom.Get(i)); ASSERT(NULL != pc);
if (-1 != prgTo->Append(pc)) { pc->AddRef(); } else { hr = E_OUTOFMEMORY; } } return THR(hr); }
//
// Create a new IUICommand object from a CPLINK_DESC structure.
//
HRESULT CplNamespace_CreateUiCommand( IUnknown *punkSite, const CPLINK_DESC& ld, IUICommand **ppc ) { ASSERT(NULL != ppc); ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
*ppc = NULL;
ICplNamespace *pns; HRESULT hr = IUnknown_QueryService(punkSite, SID_SControlPanelView, IID_ICplNamespace, (void **)&pns); if (SUCCEEDED(hr)) { hr = CPL::Create_CplUiCommand(ld.prsrcName->GetResource(pns), ld.prsrcInfotip->GetResource(pns), ld.prsrcIcon->GetResource(pns), ld.pAction, IID_IUICommand, (void **)ppc); pns->Release(); } return THR(hr); }
//
// Create a new IUIElement object for a given webview type.
// The returned IUIElement object represents the header for
// the requested webview menu.
//
HRESULT CplNamespace_CreateWebViewHeaderElement( eCPWVTYPE eType, IUIElement **ppele ) { ASSERT(0 <= eType && eCPWVTYPE_NUMTYPES > eType); ASSERT(NULL != ppele); ASSERT(!IsBadWritePtr(ppele, sizeof(*ppele)));
static const struct { LPCWSTR pszName; LPCWSTR pszInfotip; LPCWSTR pszIcon;
} rgHeaderInfo[] = { //
// eCPWVTYPE_CPANEL
//
{ MAKEINTRESOURCEW(IDS_CONTROLPANEL), MAKEINTRESOURCEW(IDS_CPTASK_CONTROLPANEL_INFOTIP), MAKEINTRESOURCEW(IDI_CPLFLD) }, //
// eCPWVTYPE_SEEALSO
//
{ MAKEINTRESOURCEW(IDS_CPTASK_SEEALSO_TITLE), MAKEINTRESOURCEW(IDS_CPTASK_SEEALSO_INFOTIP), MAKEINTRESOURCEW(IDI_CPTASK_SEEALSO) }, //
// eCPWVTYPE_TROUBLESHOOTER
//
{ MAKEINTRESOURCEW(IDS_CPTASK_TROUBLESHOOTER_TITLE), MAKEINTRESOURCEW(IDS_CPTASK_TROUBLESHOOTER_INFOTIP), MAKEINTRESOURCEW(IDI_CPTASK_TROUBLESHOOTER) }, //
// eCPWVTYPE_LEARNABOUT
//
{ MAKEINTRESOURCEW(IDS_CPTASK_LEARNABOUT_TITLE), MAKEINTRESOURCEW(IDS_CPTASK_LEARNABOUT_INFOTIP), MAKEINTRESOURCEW(IDI_CPTASK_LEARNABOUT) } };
*ppele = NULL;
HRESULT hr = Create_CplUiElement(rgHeaderInfo[eType].pszName, rgHeaderInfo[eType].pszInfotip, rgHeaderInfo[eType].pszIcon, IID_IUIElement, (void **)ppele); return THR(hr); }
//-----------------------------------------------------------------------------
// UI Command Enumeration
//-----------------------------------------------------------------------------
class IEnumCommandBase { public: virtual ~IEnumCommandBase() { } virtual HRESULT Next(IUnknown *punkSite, IUICommand **ppc) = 0; virtual HRESULT Skip(ULONG n) = 0; virtual HRESULT Reset(void) = 0; virtual HRESULT Clone(IEnumCommandBase **ppEnum) = 0; };
//
// Used to enumerate UI Command objects that originate from static
// initialization information in the CPL namespace.
//
class CEnumCommand_LinkDesc : public IEnumCommandBase { public: CEnumCommand_LinkDesc(const CPLINK_DESC **ppld); ~CEnumCommand_LinkDesc(void);
HRESULT Next(IUnknown *punkSite, IUICommand **ppc); HRESULT Skip(ULONG n); HRESULT Reset(void); HRESULT Clone(IEnumCommandBase **ppEnum);
private: const CPLINK_DESC ** const m_ppldFirst; // First item in descriptor array.
const CPLINK_DESC **m_ppldCurrent; // 'Current' item referenced.
};
//
// Used to enumerate UI Command objects that already exist in
// a DPA of IUICommand pointers. In particular, this is used
// to enumerate the UICommand objects that represent CPL applets
// in the user interface.
//
class CEnumCommand_Array : public IEnumCommandBase { public: CEnumCommand_Array(void); ~CEnumCommand_Array(void);
HRESULT Next(IUnknown *punkSite, IUICommand **ppc); HRESULT Skip(ULONG n); HRESULT Reset(void); HRESULT Clone(IEnumCommandBase **ppEnum); HRESULT Initialize(const CDpaUiCommand& rgCommands);
private: CDpaUiCommand m_rgCommands; // DPA of IUICommand ptrs.
int m_iCurrent; // 'Current' item in enumeration.
//
// Prevent copy.
//
CEnumCommand_Array(const CEnumCommand_Array& rhs); // not implemented.
CEnumCommand_Array& operator = (const CEnumCommand_Array& rhs); // not implemented.
};
//-----------------------------------------------------------------------------
// CEnumCommand_LinkDesc implementation.
//-----------------------------------------------------------------------------
CEnumCommand_LinkDesc::CEnumCommand_LinkDesc( const CPLINK_DESC **ppld ) : m_ppldFirst(ppld), m_ppldCurrent(ppld) { TraceMsg(TF_LIFE, "CEnumCommand_LinkDesc::CEnumCommand_LinkDesc, this = 0x%x", this); }
CEnumCommand_LinkDesc::~CEnumCommand_LinkDesc( void ) { TraceMsg(TF_LIFE, "CEnumCommand_LinkDesc::~CEnumCommand_LinkDesc, this = 0x%x", this); }
HRESULT CEnumCommand_LinkDesc::Next( IUnknown *punkSite, IUICommand **ppc ) { ASSERT(NULL != ppc); ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
HRESULT hr = S_FALSE; if (NULL != m_ppldCurrent && NULL != *m_ppldCurrent) { hr = CplNamespace_CreateUiCommand(punkSite, **m_ppldCurrent, ppc); m_ppldCurrent++; } return THR(hr); }
HRESULT CEnumCommand_LinkDesc::Reset( void ) { m_ppldCurrent = m_ppldFirst; return S_OK; }
HRESULT CEnumCommand_LinkDesc::Skip( ULONG n ) { if (NULL != m_ppldCurrent) { while(0 < n-- && NULL != *m_ppldCurrent) { m_ppldCurrent++; } } return 0 == n ? S_OK : S_FALSE; }
HRESULT CEnumCommand_LinkDesc::Clone( IEnumCommandBase **ppenum ) { ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
HRESULT hr = E_OUTOFMEMORY; *ppenum = new CEnumCommand_LinkDesc(m_ppldFirst); if (NULL != *ppenum) { hr = S_OK; } return THR(hr); }
//-----------------------------------------------------------------------------
// CEnumCommand_Array implementation.
//-----------------------------------------------------------------------------
CEnumCommand_Array::CEnumCommand_Array( void ) : m_iCurrent(0) { TraceMsg(TF_LIFE, "CEnumCommand_Array::CEnumCommand_Array, this = 0x%x", this); }
CEnumCommand_Array::~CEnumCommand_Array( void ) { TraceMsg(TF_LIFE, "CEnumCommand_Array::~CEnumCommand_Array, this = 0x%x", this); }
HRESULT CEnumCommand_Array::Initialize( const CDpaUiCommand& rgCommands ) { ASSERT(0 == m_rgCommands.Count()); ASSERT(0 == m_iCurrent); HRESULT hr = CplNamespace_CopyCommandArray(rgCommands, &m_rgCommands); return THR(hr); } HRESULT CEnumCommand_Array::Next( IUnknown *punkSite, IUICommand **ppc ) { ASSERT(NULL != ppc); ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
UNREFERENCED_PARAMETER(punkSite); HRESULT hr = S_FALSE; if (m_iCurrent < m_rgCommands.Count()) { *ppc = m_rgCommands.Get(m_iCurrent++); ASSERT(NULL != *ppc);
(*ppc)->AddRef(); hr = S_OK; } return THR(hr); }
HRESULT CEnumCommand_Array::Reset( void ) { m_iCurrent = 0; return S_OK; }
HRESULT CEnumCommand_Array::Skip( ULONG n ) { while(0 < n-- && m_iCurrent < m_rgCommands.Count()) { m_iCurrent++; } return 0 == n ? S_OK : S_FALSE; }
HRESULT CEnumCommand_Array::Clone( IEnumCommandBase **ppenum ) { ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
HRESULT hr = E_OUTOFMEMORY; *ppenum = new CEnumCommand_Array(); if (NULL != *ppenum) { hr = static_cast<CEnumCommand_Array *>(*ppenum)->Initialize(m_rgCommands); if (FAILED(hr)) { delete *ppenum; *ppenum = NULL; } } return THR(hr); }
//-----------------------------------------------------------------------------
// CEnumCommand
//-----------------------------------------------------------------------------
//
// Enumerates IUICommand pointers for UICommand objects in the
// Control Panel namespace.
//
class CEnumCommand : public CObjectWithSite, public IEnumUICommand { public: ~CEnumCommand(void); //
// IUnknown
//
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(void); STDMETHOD_(ULONG, Release)(void); //
// IEnumUICommand
//
STDMETHOD(Next)(ULONG celt, IUICommand **pUICommand, ULONG *pceltFetched); STDMETHOD(Skip)(ULONG celt); STDMETHOD(Reset)(void); STDMETHOD(Clone)(IEnumUICommand **ppenum);
static HRESULT CreateInstance(IUnknown *punkSite, const CPLINK_DESC **ppld, REFIID riid, void **ppvEnum); static HRESULT CreateInstance(IUnknown *punkSite, const CDpaUiCommand& rgCommands, REFIID riid, void **ppvEnum);
private: LONG m_cRef; IEnumCommandBase *m_pImpl; // Ptr to actual implementation.
CEnumCommand(void); //
// Prevent copy.
//
CEnumCommand(const CEnumCommand& rhs); // not implemented.
CEnumCommand& operator = (const CEnumCommand& rhs); // not implemented.
bool _IsRestricted(IUICommand *puic); };
CEnumCommand::CEnumCommand( void ) : m_cRef(1), m_pImpl(NULL) { TraceMsg(TF_LIFE, "CEnumCommand::CEnumCommand, this = 0x%x", this); }
CEnumCommand::~CEnumCommand( void ) { TraceMsg(TF_LIFE, "CEnumCommand::~CEnumCommand, this = 0x%x", this); delete m_pImpl; }
//
// Creates a command enumerator from an array of link descriptions
// in the CPL namespace.
//
HRESULT CEnumCommand::CreateInstance( IUnknown *punkSite, const CPLINK_DESC **ppld, REFIID riid, void **ppvOut ) { //
// Note that ppld can be NULL. It simply results in an
// empty enumerator.
//
ASSERT(NULL != punkSite); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
*ppvOut = NULL;
HRESULT hr = E_OUTOFMEMORY; CEnumCommand *pec = new CEnumCommand(); if (NULL != pec) { pec->m_pImpl = new CEnumCommand_LinkDesc(ppld); if (NULL != pec->m_pImpl) { hr = pec->QueryInterface(riid, ppvOut); if (SUCCEEDED(hr)) { hr = IUnknown_SetSite(static_cast<IUnknown *>(*ppvOut), punkSite); } } pec->Release(); } return THR(hr); }
//
// Creates a command enumerator from a DPA of IUICommand ptrs.
//
HRESULT CEnumCommand::CreateInstance( IUnknown *punkSite, const CDpaUiCommand& rgCommands, REFIID riid, void **ppvOut ) { ASSERT(NULL != punkSite); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
*ppvOut = NULL;
HRESULT hr = E_OUTOFMEMORY; CEnumCommand *pec = new CEnumCommand(); if (NULL != pec) { pec->m_pImpl = new CEnumCommand_Array(); if (NULL != pec->m_pImpl) { hr = static_cast<CEnumCommand_Array *>(pec->m_pImpl)->Initialize(rgCommands); if (SUCCEEDED(hr)) { hr = pec->QueryInterface(riid, ppvOut); if (SUCCEEDED(hr)) { hr = IUnknown_SetSite(static_cast<IUnknown *>(*ppvOut), punkSite); } } } pec->Release(); } return THR(hr); }
STDMETHODIMP CEnumCommand::QueryInterface( REFIID riid, void **ppv ) { ASSERT(NULL != ppv); ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
static const QITAB qit[] = { QITABENT(CEnumCommand, IEnumUICommand), QITABENT(CEnumCommand, IObjectWithSite), { 0 }, }; HRESULT hr = QISearch(this, qit, riid, ppv);
return E_NOINTERFACE == hr ? hr : THR(hr); }
STDMETHODIMP_(ULONG) CEnumCommand::AddRef( void ) { return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) CEnumCommand::Release( void ) { ASSERT( 0 != m_cRef ); ULONG cRef = InterlockedDecrement(&m_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
STDMETHODIMP CEnumCommand::Next( ULONG celt, IUICommand **ppUICommand, ULONG *pceltFetched ) { ASSERT(NULL != ppUICommand); ASSERT(!IsBadWritePtr(ppUICommand, sizeof(*ppUICommand) * celt)); ASSERT(NULL != m_pImpl);
HRESULT hr = S_OK;
ULONG celtFetched = 0; while(S_OK == hr && 0 < celt) { ASSERT(NULL != CObjectWithSite::_punkSite); IUICommand *puic; //
// This is a little weird. I pass the site ptr to the
// Next() method but then also set the returned object's
// site when it's returned by Next(). Why not just set
// the site in the Next() implementation? Next() needs the site
// ptr to pass through to any IResSrc::GetResource implementation
// when retrieving the resources for any given UI command object.
// This is because the resource used can vary depending upon state
// information stored in the namespace. However, to simplify
// lifetime management, I want to 'set' the site on the returned
// objects in only one place; this place. That way, the derived
// enumerator instance attached to m_pImpl doesn't need to worry
// about setting the site. We do it in one place for all
// implementations. [brianau - 3/16/01]
//
hr = m_pImpl->Next(CObjectWithSite::_punkSite, &puic); if (S_OK == hr) { //
// It's important that we set the object's 'site' before
// checking the restriction. The restriction checking
// code requires access to the CplNamespace which is obtained
// through the site.
//
hr = IUnknown_SetSite(puic, CObjectWithSite::_punkSite); if (SUCCEEDED(hr)) { if (!_IsRestricted(puic)) { celt--; celtFetched++; (*ppUICommand++ = puic)->AddRef(); } } puic->Release(); } } if (NULL != pceltFetched) { *pceltFetched = celtFetched; } return THR(hr); }
STDMETHODIMP CEnumCommand::Skip( ULONG celt ) { ASSERT(NULL != m_pImpl);
HRESULT hr = m_pImpl->Skip(celt); return THR(hr); }
STDMETHODIMP CEnumCommand::Reset( void ) { ASSERT(NULL != m_pImpl);
HRESULT hr = m_pImpl->Reset(); return THR(hr); }
STDMETHODIMP CEnumCommand::Clone( IEnumUICommand **ppenum ) { ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum))); ASSERT(NULL != m_pImpl);
*ppenum = NULL;
HRESULT hr = E_OUTOFMEMORY; CEnumCommand *pe = new CEnumCommand(); if (NULL != pe) { hr = m_pImpl->Clone(&(pe->m_pImpl)); if (SUCCEEDED(hr)) { hr = pe->QueryInterface(IID_IEnumUICommand, (void **)ppenum); } pe->Release(); } return THR(hr); }
bool CEnumCommand::_IsRestricted( IUICommand *puic ) { ASSERT(NULL != puic);
bool bRestricted = false;
UISTATE uis; HRESULT hr = puic->get_State(NULL, TRUE, &uis); if (SUCCEEDED(hr)) { if (UIS_HIDDEN == uis) { bRestricted = true; } } return bRestricted; }
//-----------------------------------------------------------------------------
// CCplWebViewInfo
//-----------------------------------------------------------------------------
class CCplWebViewInfo : public ICplWebViewInfo { public: ~CCplWebViewInfo(void); //
// IUnknown
//
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(void); STDMETHOD_(ULONG, Release)(void); //
// IEnumCplWebViewInfo
//
STDMETHOD(get_Header)(IUIElement **ppele); STDMETHOD(get_Style)(DWORD *pdwFlags); STDMETHOD(EnumTasks)(IEnumUICommand **ppenum);
static HRESULT CreateInstance(IUIElement *peHeader, IEnumUICommand *penum, DWORD dwStyle, REFIID riid, void **ppvOut);
private: LONG m_cRef; IUIElement *m_peHeader; // The webview menu header.
IEnumUICommand *m_penumUiCommand; // The webview menu tasks.
DWORD m_dwStyle; // Style flags.
CCplWebViewInfo(void); };
CCplWebViewInfo::CCplWebViewInfo( void ) : m_cRef(1), m_peHeader(NULL), m_penumUiCommand(NULL), m_dwStyle(0) { TraceMsg(TF_LIFE, "CCplWebViewInfo::CCplWebViewInfo, this = 0x%x", this); }
CCplWebViewInfo::~CCplWebViewInfo( void ) { TraceMsg(TF_LIFE, "CCplWebViewInfo::~CCplWebViewInfo, this = 0x%x", this); ATOMICRELEASE(m_peHeader); ATOMICRELEASE(m_penumUiCommand); }
HRESULT CCplWebViewInfo::CreateInstance( // [static]
IUIElement *peHeader, IEnumUICommand *penum, DWORD dwStyle, REFIID riid, void **ppvOut ) { ASSERT(NULL != peHeader); ASSERT(NULL != penum); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
*ppvOut = NULL;
HRESULT hr = E_OUTOFMEMORY; CCplWebViewInfo *pwvi = new CCplWebViewInfo(); if (NULL != pwvi) { hr = pwvi->QueryInterface(riid, ppvOut); if (SUCCEEDED(hr)) { (pwvi->m_peHeader = peHeader)->AddRef(); (pwvi->m_penumUiCommand = penum)->AddRef();
pwvi->m_dwStyle = dwStyle; } pwvi->Release(); } return THR(hr); }
STDMETHODIMP CCplWebViewInfo::QueryInterface( REFIID riid, void **ppv ) { ASSERT(NULL != ppv); ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
static const QITAB qit[] = { QITABENT(CCplWebViewInfo, ICplWebViewInfo), { 0 }, }; HRESULT hr = QISearch(this, qit, riid, ppv);
return E_NOINTERFACE == hr ? hr : THR(hr); }
STDMETHODIMP_(ULONG) CCplWebViewInfo::AddRef( void ) { return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) CCplWebViewInfo::Release( void ) { ASSERT( 0 != m_cRef ); ULONG cRef = InterlockedDecrement(&m_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
STDMETHODIMP CCplWebViewInfo::get_Header( IUIElement **ppele ) { ASSERT(NULL != ppele); ASSERT(!IsBadWritePtr(ppele, sizeof(*ppele)));
HRESULT hr = S_OK;
(*ppele = m_peHeader)->AddRef();
return THR(hr); }
STDMETHODIMP CCplWebViewInfo::get_Style( DWORD *pdwStyle ) { ASSERT(NULL != pdwStyle); ASSERT(!IsBadWritePtr(pdwStyle, sizeof(*pdwStyle)));
*pdwStyle = m_dwStyle; return S_OK; }
STDMETHODIMP CCplWebViewInfo::EnumTasks( IEnumUICommand **ppenum ) { ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
HRESULT hr = S_OK;
(*ppenum = m_penumUiCommand)->AddRef();
return THR(hr); }
//-----------------------------------------------------------------------------
// CEnumCplWebViewInfo
//-----------------------------------------------------------------------------
struct ECWVI_ITEM { eCPWVTYPE eType; const CPLINK_DESC **rgpDesc; // Ptr to nul-term array of link desc ptrs.
bool bRestricted; // Is item restricted from usage?
bool bEnhancedMenu; // Render as a 'special' list in webview?
};
class CEnumCplWebViewInfo : public CObjectWithSite, public IEnumCplWebViewInfo { public: ~CEnumCplWebViewInfo(void); //
// IUnknown
//
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(void); STDMETHOD_(ULONG, Release)(void); //
// IEnumCplWebViewInfo
//
STDMETHOD(Next)(ULONG celt, ICplWebViewInfo **ppwvi, ULONG *pceltFetched); STDMETHOD(Skip)(ULONG celt); STDMETHOD(Reset)(void); STDMETHOD(Clone)(IEnumCplWebViewInfo **ppenum);
static HRESULT CreateInstance(IUnknown *punkSite, const ECWVI_ITEM *prgwvi, UINT cItems, REFIID riid, void **ppvOut);
private: LONG m_cRef; int m_iCurrent; CDpa<ICplWebViewInfo, CDpaDestroyer_Release<ICplWebViewInfo> > m_rgwvi;
CEnumCplWebViewInfo(void); HRESULT _Initialize(IUnknown *punkSite, const ECWVI_ITEM *prgwvi, UINT cItems);
//
// Prevent copy.
//
CEnumCplWebViewInfo(const CEnumCplWebViewInfo& rhs); // not implemented.
CEnumCplWebViewInfo& operator = (const CEnumCplWebViewInfo& rhs); // not implemented.
};
CEnumCplWebViewInfo::CEnumCplWebViewInfo( void ) : m_cRef(1), m_iCurrent(0) { TraceMsg(TF_LIFE, "CEnumCplWebViewInfo::CEnumCplWebViewInfo, this = 0x%x", this); }
CEnumCplWebViewInfo::~CEnumCplWebViewInfo( void ) { TraceMsg(TF_LIFE, "CEnumCplWebViewInfo::~CEnumCplWebViewInfo, this = 0x%x", this); }
HRESULT CEnumCplWebViewInfo::CreateInstance( IUnknown *punkSite, const ECWVI_ITEM *prgwvi, UINT cItems, REFIID riid, void **ppvOut ) { ASSERT(NULL != punkSite); ASSERT(NULL != prgwvi); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
*ppvOut = NULL;
HRESULT hr = E_OUTOFMEMORY; CEnumCplWebViewInfo *pewvi = new CEnumCplWebViewInfo(); if (NULL != pewvi) { hr = pewvi->_Initialize(punkSite, prgwvi, cItems); if (SUCCEEDED(hr)) { hr = pewvi->QueryInterface(riid, ppvOut); } pewvi->Release(); } return THR(hr); }
STDMETHODIMP CEnumCplWebViewInfo::QueryInterface( REFIID riid, void **ppv ) { ASSERT(NULL != ppv); ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
static const QITAB qit[] = { QITABENT(CEnumCplWebViewInfo, IEnumCplWebViewInfo), QITABENT(CEnumCplWebViewInfo, IObjectWithSite), { 0 }, }; HRESULT hr = QISearch(this, qit, riid, ppv);
return E_NOINTERFACE == hr ? hr : THR(hr); }
STDMETHODIMP_(ULONG) CEnumCplWebViewInfo::AddRef( void ) { return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) CEnumCplWebViewInfo::Release( void ) { ASSERT( 0 != m_cRef ); ULONG cRef = InterlockedDecrement(&m_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
STDMETHODIMP CEnumCplWebViewInfo::Next( ULONG celt, ICplWebViewInfo **ppwvi, ULONG *pceltFetched ) { ASSERT(NULL != ppwvi); ASSERT(!IsBadWritePtr(ppwvi, sizeof(*ppwvi) * celt));
ULONG celtFetched = 0; while(m_iCurrent < m_rgwvi.Count() && 0 < celt) { *ppwvi = m_rgwvi.Get(m_iCurrent++);
ASSERT(NULL != *ppwvi); (*ppwvi)->AddRef();
celt--; celtFetched++; ppwvi++; } if (NULL != pceltFetched) { *pceltFetched = celtFetched; } return 0 == celt ? S_OK : S_FALSE; }
STDMETHODIMP CEnumCplWebViewInfo::Reset( void ) { m_iCurrent = 0; return S_OK; }
STDMETHODIMP CEnumCplWebViewInfo::Skip( ULONG n ) { while(0 < n-- && m_iCurrent < m_rgwvi.Count()) { m_iCurrent++; } return 0 == n ? S_OK : S_FALSE; }
STDMETHODIMP CEnumCplWebViewInfo::Clone( IEnumCplWebViewInfo **ppenum ) { ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
*ppenum = NULL;
HRESULT hr = E_OUTOFMEMORY; CEnumCplWebViewInfo *penum = new CEnumCplWebViewInfo(); if (NULL != *ppenum) { for (int i = 0; SUCCEEDED(hr) && i < m_rgwvi.Count(); i++) { ICplWebViewInfo *pwvi = m_rgwvi.Get(i); ASSERT(NULL != pwvi);
if (-1 != penum->m_rgwvi.Append(pwvi)) { pwvi->AddRef(); } else { hr = E_OUTOFMEMORY; } } if (SUCCEEDED(hr)) { hr = penum->QueryInterface(IID_IEnumCplWebViewInfo, (void **)ppenum); } penum->Release(); } return THR(hr); }
HRESULT CEnumCplWebViewInfo::_Initialize( IUnknown *punkSite, const ECWVI_ITEM *prgwvi, UINT cItems ) { ASSERT(NULL != punkSite); ASSERT(NULL != prgwvi);
IUnknown *punk; HRESULT hr = QueryInterface(IID_IUnknown, (void **)&punk); if (SUCCEEDED(hr)) { hr = IUnknown_SetSite(punk, punkSite); if (SUCCEEDED(hr)) { for (UINT i = 0; i < cItems; i++) { if (!prgwvi[i].bRestricted) { IEnumUICommand *penum;
hr = CEnumCommand::CreateInstance(CObjectWithSite::_punkSite, prgwvi[i].rgpDesc, IID_IEnumUICommand, (void **)&penum); if (SUCCEEDED(hr)) { IUIElement *peHeader; hr = CplNamespace_CreateWebViewHeaderElement(prgwvi[i].eType, &peHeader); if (SUCCEEDED(hr)) { DWORD dwStyle = 0; if (prgwvi[i].bEnhancedMenu) { dwStyle |= SFVMWVF_SPECIALTASK; } ICplWebViewInfo *pwvi; hr = CCplWebViewInfo::CreateInstance(peHeader, penum, dwStyle, IID_ICplWebViewInfo, (void **)&pwvi); if (SUCCEEDED(hr)) { if (-1 == m_rgwvi.Append(pwvi)) { pwvi->Release(); hr = E_OUTOFMEMORY; } } peHeader->Release(); } penum->Release(); } } } } punk->Release(); } return THR(hr); }
//-----------------------------------------------------------------------------
// CCplCategory
//-----------------------------------------------------------------------------
class CCplCategory : public CObjectWithSite, public ICplCategory { public: ~CCplCategory(void); //
// IUnknown
//
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(void); STDMETHOD_(ULONG, Release)(void); //
// ICplCategory
//
STDMETHOD(GetCategoryID)(eCPCAT *pID); STDMETHOD(GetUiCommand)(IUICommand **ppele); STDMETHOD(EnumTasks)(IEnumUICommand **ppenum); STDMETHOD(EnumCplApplets)(IEnumUICommand **ppenum); STDMETHOD(EnumWebViewInfo)(DWORD dwFlags, IEnumCplWebViewInfo **ppenum); STDMETHOD(GetHelpURL)(LPWSTR pszURL, UINT cchURL);
static HRESULT CreateInstance(const CPCAT_DESC *pDesc, const CDpaUiCommand& rgCplApplets, REFIID riid, void **ppvOut);
private: LONG m_cRef; const CPCAT_DESC *m_pDesc; // Initialization data.
CDpaUiCommand m_rgCplApplets; // Cached list of CPL applet links.
CCplCategory(void); //
// Prevent copy.
//
CCplCategory(const CCplCategory& rhs); // not implemented.
CCplCategory& operator = (const CCplCategory& rhs); // not implemented.
HRESULT _Initialize(const CPCAT_DESC *pDesc, const CDpaUiCommand& rgCplApplets); bool _CplAppletsLoaded(void) const; };
CCplCategory::CCplCategory( void ) : m_cRef(1), m_pDesc(NULL) { TraceMsg(TF_LIFE, "CCplCategory::CCplCategory, this = 0x%x", this); }
CCplCategory::~CCplCategory( void ) { TraceMsg(TF_LIFE, "CCplCategory::~CCplCategory, this = 0x%x", this); }
HRESULT CCplCategory::CreateInstance( const CPCAT_DESC *pDesc, const CDpaUiCommand& rgCplApplets, REFIID riid, void **ppvOut ) { ASSERT(NULL != pDesc); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
*ppvOut = NULL;
HRESULT hr = E_OUTOFMEMORY; CCplCategory *pc = new CCplCategory(); if (NULL != pc) { hr = pc->_Initialize(pDesc, rgCplApplets); if (SUCCEEDED(hr)) { hr = pc->QueryInterface(riid, ppvOut); } pc->Release(); } return THR(hr); }
STDMETHODIMP CCplCategory::QueryInterface( REFIID riid, void **ppv ) { ASSERT(NULL != ppv); ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
static const QITAB qit[] = { QITABENT(CCplCategory, ICplCategory), QITABENT(CCplCategory, IObjectWithSite), { 0 }, }; HRESULT hr = QISearch(this, qit, riid, ppv);
return E_NOINTERFACE == hr ? hr : THR(hr); }
STDMETHODIMP_(ULONG) CCplCategory::AddRef( void ) { return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) CCplCategory::Release( void ) { ASSERT( 0 != m_cRef ); ULONG cRef = InterlockedDecrement(&m_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
STDMETHODIMP CCplCategory::GetUiCommand( IUICommand **ppc ) { DBG_ENTER(FTF_CPANEL, "CCplCategory::GetUiCommand");
ASSERT(NULL != m_pDesc); ASSERT(NULL != m_pDesc->pLink); ASSERT(NULL != ppc); ASSERT(!IsBadWritePtr(ppc, sizeof(*ppc)));
HRESULT hr = CplNamespace_CreateUiCommand(CObjectWithSite::_punkSite, *(m_pDesc->pLink), ppc); if (SUCCEEDED(hr)) { hr = IUnknown_SetSite(*ppc, CObjectWithSite::_punkSite); }
DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::GetUiCommand", hr); return THR(hr); }
STDMETHODIMP CCplCategory::EnumWebViewInfo( DWORD dwFlags, IEnumCplWebViewInfo **ppenum ) { DBG_ENTER(FTF_CPANEL, "CCplCategory::EnumWebViewInfo");
ASSERT(NULL != m_pDesc); ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
UNREFERENCED_PARAMETER(dwFlags);
const ECWVI_ITEM rgItems[] = { { eCPWVTYPE_SEEALSO, m_pDesc->slinks.ppSeeAlsoLinks, false, false }, { eCPWVTYPE_TROUBLESHOOT, m_pDesc->slinks.ppTroubleshootLinks, false, false }, { eCPWVTYPE_LEARNABOUT, m_pDesc->slinks.ppLearnAboutLinks, false, false } };
HRESULT hr = CEnumCplWebViewInfo::CreateInstance(CObjectWithSite::_punkSite, rgItems, ARRAYSIZE(rgItems), IID_IEnumCplWebViewInfo, (void **)ppenum);
DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::EnumWebViewInfo", hr); return THR(hr); }
STDMETHODIMP CCplCategory::EnumTasks( IEnumUICommand **ppenum ) { DBG_ENTER(FTF_CPANEL, "CCplCategory::EnumTasks");
ASSERT(NULL != m_pDesc); ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
HRESULT hr = CEnumCommand::CreateInstance(CObjectWithSite::_punkSite, m_pDesc->ppTaskLinks, IID_IEnumUICommand, (void **)ppenum);
DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::EnumTasks", hr); return THR(hr); }
STDMETHODIMP CCplCategory::EnumCplApplets( IEnumUICommand **ppenum ) { DBG_ENTER(FTF_CPANEL, "CCplCategory::EnumCplApplets");
ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
HRESULT hr = CEnumCommand::CreateInstance(CObjectWithSite::_punkSite, m_rgCplApplets, IID_IEnumUICommand, (void **)ppenum);
DBG_EXIT_HRES(FTF_CPANEL, "CCplCategory::EnumCplApplets", hr); return THR(hr); }
STDMETHODIMP CCplCategory::GetCategoryID( eCPCAT *pID ) { ASSERT(NULL != pID); ASSERT(!IsBadWritePtr(pID, sizeof(*pID)));
*pID = m_pDesc->idCategory; return S_OK; }
STDMETHODIMP CCplCategory::GetHelpURL( LPWSTR pszURL, UINT cchURL ) { ASSERT(NULL != pszURL); ASSERT(!IsBadWritePtr(pszURL, cchURL * sizeof(*pszURL))); return CPL::BuildHssHelpURL(m_pDesc->pszHelpSelection, pszURL, cchURL); }
HRESULT CCplCategory::_Initialize( const CPCAT_DESC *pDesc, const CDpaUiCommand& rgCplApplets ) { ASSERT(NULL != pDesc); ASSERT(NULL == m_pDesc);
m_pDesc = pDesc; HRESULT hr = CplNamespace_CopyCommandArray(rgCplApplets, &m_rgCplApplets);
return THR(hr); }
//-----------------------------------------------------------------------------
// CTriState
// This is a trivial class to allow representation of a uninitialized boolean
// value. Used by CCplNamespace for it's storage of cached 'restriction'
// values. Internally, -1 == 'uninitialized, 0 == false and 1 == true.
//-----------------------------------------------------------------------------
class CTriState { public: CTriState(void) : m_iVal(-1) { }
operator bool() const { ASSERT(!_Invalid()); return (!_Invalid() ? !!m_iVal : false); }
CTriState& operator = (bool bValue) { m_iVal = bValue ? 1 : 0; return *this; }
bool IsInvalid(void) const { return _Invalid(); } private: int m_iVal;
void _Set(bool bValue) { m_iVal = bValue ? 1 : 0; }
bool _Invalid(void) const { return (-1 == m_iVal); } };
//-----------------------------------------------------------------------------
// CCplNamespace
//-----------------------------------------------------------------------------
class CCplNamespace : public CObjectWithSite, public ICplNamespace { public: ~CCplNamespace(void);
//
// IUnknown
//
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(void); STDMETHOD_(ULONG, Release)(void); //
// ICplNamespace
//
STDMETHOD(GetCategory)(eCPCAT eCategory, ICplCategory **ppcat); STDMETHOD(EnumWebViewInfo)(DWORD dwFlags, IEnumCplWebViewInfo **ppenum); STDMETHOD(EnumClassicWebViewInfo)(DWORD dwFlags, IEnumCplWebViewInfo **ppenum); STDMETHOD(RefreshIDs)(IEnumIDList *penumIDs); STDMETHOD_(BOOL, IsServer)(void); STDMETHOD_(BOOL, IsProfessional)(void); STDMETHOD_(BOOL, IsPersonal)(void); STDMETHOD_(BOOL, IsUserAdmin)(void); STDMETHOD_(BOOL, IsUserOwner)(void); STDMETHOD_(BOOL, IsUserStandard)(void); STDMETHOD_(BOOL, IsUserLimited)(void); STDMETHOD_(BOOL, IsUserGuest)(void); STDMETHOD_(BOOL, IsOnDomain)(void); STDMETHOD_(BOOL, IsX86)(void); STDMETHOD_(BOOL, AllowUserManager)(void); STDMETHOD_(BOOL, UsePersonalUserManager)(void); STDMETHOD_(BOOL, AllowDeskCpl)(void); STDMETHOD_(BOOL, AllowDeskCplTab_Background)(void); STDMETHOD_(BOOL, AllowDeskCplTab_Screensaver)(void); STDMETHOD_(BOOL, AllowDeskCplTab_Appearance)(void); STDMETHOD_(BOOL, AllowDeskCplTab_Settings)(void);
static HRESULT CreateInstance(IEnumIDList *penumIDs, REFIID riid, void **ppvOut);
private: LONG m_cRef; ICplCategory *m_rgpCategories[eCPCAT_NUMCATEGORIES]; CDpaUiCommand m_rgCplApplets[eCPCAT_NUMCATEGORIES]; IEnumIDList *m_penumIDs; CTriState m_SkuSvr; CTriState m_SkuPro; CTriState m_SkuPer; CTriState m_Admin; CTriState m_UserOwner; CTriState m_UserStandard; CTriState m_UserLimited; CTriState m_UserGuest; CTriState m_Domain; CTriState m_AllowUserManager; CTriState m_PersonalUserManager; CTriState m_AllowDeskCpl; CTriState m_rgAllowDeskCplTabs[CPLTAB_DESK_MAX];
CCplNamespace(void); //
// Prevent copy.
//
CCplNamespace(const CCplNamespace& rhs); // not implemented.
CCplNamespace& operator = (const CCplNamespace& rhs); // not implemented.
HRESULT _Initialize(IEnumIDList *penumIDs); HRESULT _SetIDList(IEnumIDList *penumIDs); HRESULT _IsValidCategoryID(int iCategory) const; HRESULT _CategorizeCplApplets(void); HRESULT _LoadSeeAlsoLinks(void); HRESULT _AddSeeAlso(IUICommand *pc); HRESULT _CategorizeCplApplet(IShellFolder2 *psf2Cpanel, LPCITEMIDLIST pidlItem); BOOL _UserAcctType(CTriState *pts); void _GetUserAccountType(void); BOOL _AllowDeskCplTab(eDESKCPLTAB eTab); void _DestroyCategories(void); void _ClearCplApplets(void); };
CCplNamespace::CCplNamespace( void ) : m_cRef(1), m_penumIDs(NULL) { TraceMsg(TF_LIFE, "CCplNamespace::CCplNamespace, this = 0x%x", this); ZeroMemory(m_rgpCategories, sizeof(m_rgpCategories)); }
CCplNamespace::~CCplNamespace( void ) { TraceMsg(TF_LIFE, "CCplNamespace::~CCplNamespace, this = 0x%x", this); _DestroyCategories(); ATOMICRELEASE(m_penumIDs); }
HRESULT CCplNamespace::CreateInstance( IEnumIDList *penumIDs, REFIID riid, void **ppvOut ) { ASSERT(NULL != penumIDs); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
*ppvOut = NULL;
HRESULT hr = E_OUTOFMEMORY; CCplNamespace *pns = new CCplNamespace(); if (NULL != pns) { hr = pns->_Initialize(penumIDs); if (SUCCEEDED(hr)) { hr = pns->QueryInterface(riid, ppvOut); } pns->Release(); } return THR(hr); }
STDMETHODIMP CCplNamespace::QueryInterface( REFIID riid, void **ppv ) { ASSERT(NULL != ppv); ASSERT(!IsBadWritePtr(ppv, sizeof(*ppv)));
static const QITAB qit[] = { QITABENT(CCplNamespace, ICplNamespace), QITABENT(CCplNamespace, IObjectWithSite), { 0 }, }; HRESULT hr = QISearch(this, qit, riid, ppv);
return E_NOINTERFACE == hr ? hr : THR(hr); }
STDMETHODIMP_(ULONG) CCplNamespace::AddRef( void ) { ULONG cRef = InterlockedIncrement(&m_cRef); TraceMsg(TF_LIFE, "CCplNamespace::AddRef %d->%d", cRef - 1, cRef); return cRef; }
STDMETHODIMP_(ULONG) CCplNamespace::Release( void ) { ASSERT( 0 != m_cRef ); ULONG cRef = InterlockedDecrement(&m_cRef); TraceMsg(TF_LIFE, "CCplNamespace::Release %d<-%d", cRef, cRef+1); if ( 0 == cRef ) { delete this; } return cRef; }
STDMETHODIMP CCplNamespace::EnumWebViewInfo( DWORD dwFlags, IEnumCplWebViewInfo **ppenum ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::EnumWebViewInfo");
ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
const bool bNoViewSwitch = (0 != (CPVIEW_EF_NOVIEWSWITCH & dwFlags));
const ECWVI_ITEM rgItems[] = { { eCPWVTYPE_CPANEL, g_rgpLink_Cpl_SwToClassicView, bNoViewSwitch, true }, { eCPWVTYPE_SEEALSO, g_rgpLink_Cpl_SeeAlso, false, false } };
HRESULT hr = CEnumCplWebViewInfo::CreateInstance(CObjectWithSite::_punkSite, rgItems, ARRAYSIZE(rgItems), IID_IEnumCplWebViewInfo, (void **)ppenum);
DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::EnumWebViewInfo", hr); return THR(hr); }
STDMETHODIMP CCplNamespace::EnumClassicWebViewInfo( DWORD dwFlags, IEnumCplWebViewInfo **ppenum ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::EnumClassicWebViewInfo");
ASSERT(NULL != ppenum); ASSERT(!IsBadWritePtr(ppenum, sizeof(*ppenum)));
const bool bNoViewSwitch = (0 != (CPVIEW_EF_NOVIEWSWITCH & dwFlags));
const ECWVI_ITEM rgItems[] = { { eCPWVTYPE_CPANEL, g_rgpLink_Cpl_SwToCategoryView, bNoViewSwitch, true }, { eCPWVTYPE_SEEALSO, g_rgpLink_Cpl_SeeAlso, false, false } };
HRESULT hr = CEnumCplWebViewInfo::CreateInstance(CObjectWithSite::_punkSite, rgItems, ARRAYSIZE(rgItems), IID_IEnumCplWebViewInfo, (void **)ppenum);
DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::EnumClassicWebViewInfo", hr); return THR(hr); }
STDMETHODIMP CCplNamespace::GetCategory( eCPCAT eCategory, ICplCategory **ppcat ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::GetCategory"); TraceMsg(FTF_CPANEL, "Category ID = %d", eCategory);
ASSERT(S_OK == _IsValidCategoryID(eCategory)); ASSERT(NULL != ppcat); ASSERT(!IsBadWritePtr(ppcat, sizeof(*ppcat)));
HRESULT hr = S_OK;
*ppcat = NULL;
if (NULL == m_rgpCategories[eCategory]) { hr = CCplCategory::CreateInstance(g_rgpCplCatInfo[eCategory], m_rgCplApplets[eCategory], IID_ICplCategory, (void **)&m_rgpCategories[eCategory]); if (SUCCEEDED(hr)) { ASSERT(NULL != CObjectWithSite::_punkSite); hr = IUnknown_SetSite(m_rgpCategories[eCategory], CObjectWithSite::_punkSite); } } if (SUCCEEDED(hr)) { *ppcat = m_rgpCategories[eCategory]; (*ppcat)->AddRef(); }
DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::GetCategory", hr); return THR(hr); }
STDMETHODIMP CCplNamespace::RefreshIDs( IEnumIDList *penumIDs ) { return _SetIDList(penumIDs); }
BOOL CCplNamespace::IsX86(void) { #ifdef _X86_
return true; #else
return false; #endif
}
BOOL CCplNamespace::IsServer(void) { if (m_SkuSvr.IsInvalid()) { m_SkuSvr = !!IsOsServer(); } return m_SkuSvr; }
BOOL CCplNamespace::IsPersonal(void) { if (m_SkuPer.IsInvalid()) { m_SkuPer = !!IsOsPersonal(); } return m_SkuPer; }
BOOL CCplNamespace::IsProfessional(void) { if (m_SkuPro.IsInvalid()) { m_SkuPro = !!IsOsProfessional(); } return m_SkuPro; }
BOOL CCplNamespace::IsOnDomain(void) { if (m_Domain.IsInvalid()) { m_Domain = !!IsConnectedToDomain(); } return m_Domain; }
BOOL CCplNamespace::IsUserAdmin(void) { if (m_Admin.IsInvalid()) { m_Admin = !!CPL::IsUserAdmin(); } return m_Admin; }
BOOL CCplNamespace::IsUserOwner(void) { return _UserAcctType(&m_UserOwner); }
BOOL CCplNamespace::IsUserStandard(void) { return _UserAcctType(&m_UserStandard); }
BOOL CCplNamespace::IsUserLimited(void) { return _UserAcctType(&m_UserLimited); }
BOOL CCplNamespace::IsUserGuest(void) { return _UserAcctType(&m_UserGuest); }
BOOL CCplNamespace::UsePersonalUserManager(void) { if (m_PersonalUserManager.IsInvalid()) { m_PersonalUserManager = (IsX86() && (IsPersonal() || (IsProfessional() && !IsOnDomain()))); } return m_PersonalUserManager; }
BOOL CCplNamespace::AllowUserManager(void) { if (m_AllowUserManager.IsInvalid()) { m_AllowUserManager = IsAppletEnabled(L"nusrmgr.cpl", MAKEINTRESOURCEW(IDS_CPL_USERACCOUNTS)); } return m_AllowUserManager; }
BOOL CCplNamespace::_AllowDeskCplTab(eDESKCPLTAB eTab) { if (m_rgAllowDeskCplTabs[eTab].IsInvalid()) { m_rgAllowDeskCplTabs[eTab] = DeskCPL_IsTabPresent(eTab); } return m_rgAllowDeskCplTabs[eTab]; }
BOOL CCplNamespace::AllowDeskCplTab_Background(void) { return _AllowDeskCplTab(CPLTAB_DESK_BACKGROUND); }
BOOL CCplNamespace::AllowDeskCplTab_Screensaver(void) { return _AllowDeskCplTab(CPLTAB_DESK_SCREENSAVER); }
BOOL CCplNamespace::AllowDeskCplTab_Appearance(void) { return _AllowDeskCplTab(CPLTAB_DESK_APPEARANCE); }
BOOL CCplNamespace::AllowDeskCplTab_Settings(void) { return _AllowDeskCplTab(CPLTAB_DESK_SETTINGS); }
BOOL CCplNamespace::AllowDeskCpl(void) { if (m_AllowDeskCpl.IsInvalid()) { m_AllowDeskCpl = IsAppletEnabled(L"desk.cpl", MAKEINTRESOURCEW(IDS_CPL_DISPLAY)); } return m_AllowDeskCpl; }
//
// Retrieves the account type for the current user and updates
// the cached account type members accordingly.
//
void CCplNamespace::_GetUserAccountType(void) { eACCOUNTTYPE eType; if (SUCCEEDED(THR(CPL::GetUserAccountType(&eType)))) { m_UserLimited = (eACCOUNTTYPE_LIMITED == eType); m_UserStandard = (eACCOUNTTYPE_STANDARD == eType); m_UserGuest = (eACCOUNTTYPE_GUEST == eType); m_UserOwner = (eACCOUNTTYPE_OWNER == eType); } }
//
// Determins the state of a given account type member.
//
BOOL CCplNamespace::_UserAcctType(CTriState *pts) { if (pts->IsInvalid()) { _GetUserAccountType(); } return *pts; }
HRESULT CCplNamespace::_IsValidCategoryID( int iCategory ) const { HRESULT hr = E_FAIL; if (0 <= iCategory && ARRAYSIZE(m_rgpCategories) > iCategory) { hr = S_OK; } return THR(hr); }
HRESULT CCplNamespace::_Initialize( IEnumIDList *penumIDs ) { ASSERT(NULL != penumIDs);
HRESULT hr = _SetIDList(penumIDs); return THR(hr); }
HRESULT CCplNamespace::_SetIDList( IEnumIDList *penumIDs ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::_SetIDList");
ASSERT(NULL != penumIDs); ATOMICRELEASE(m_penumIDs); (m_penumIDs = penumIDs)->AddRef(); //
// We have a new set of IDs so we need to re-categorize them.
//
HRESULT hr = _CategorizeCplApplets();
DBG_EXIT(FTF_CPANEL, "CCplNamespace::_SetIDList"); return THR(hr); }
//
// Destroy all category objects in our array of categories.
//
void CCplNamespace::_DestroyCategories( void ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::_DestroyCategories");
for (int i = 0; i < ARRAYSIZE(m_rgpCategories); i++) { ATOMICRELEASE(m_rgpCategories[i]); } DBG_EXIT(FTF_CPANEL, "CCplNamespace::_DestroyCategories"); }
void CCplNamespace::_ClearCplApplets( void ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::_ClearCplApplets");
for (int i = 0; i < ARRAYSIZE(m_rgCplApplets); i++) { m_rgCplApplets[i].Clear(); } DBG_EXIT(FTF_CPANEL, "CCplNamespace::_ClearCplApplets"); }
//
// Load and categorize all of the CPL applets in the Control Panel folder.
//
HRESULT CCplNamespace::_CategorizeCplApplets( void ) { DBG_ENTER(FTF_CPANEL, "CCplNamespace::_CategorizeCplApplets"); //
// Destroy any existing categories and CPL applets that we have
// already categorized.
//
_DestroyCategories(); _ClearCplApplets(); LPITEMIDLIST pidlFolder; HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_CONTROLS, &pidlFolder); if (SUCCEEDED(hr)) { IShellFolder *psfDesktop; hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) { IShellFolder2 *psf2Cpanel; hr = psfDesktop->BindToObject(pidlFolder, NULL, IID_IShellFolder2, (void **)&psf2Cpanel); if (SUCCEEDED(hr)) { LPITEMIDLIST pidlItem; ULONG celt = 0; while(S_OK == (hr = m_penumIDs->Next(1, &pidlItem, &celt))) { //
// Note that we continue the enumeration if loading a
// particular applet fails.
//
_CategorizeCplApplet(psf2Cpanel, pidlItem); ILFree(pidlItem); } psf2Cpanel->Release(); } psfDesktop->Release(); } ILFree(pidlFolder); } DBG_EXIT_HRES(FTF_CPANEL, "CCplNamespace::_CategorizeCplApplets", hr); return THR(hr); }
//
// Load one CPL applet into the category's DPA of associated CPL applets.
//
HRESULT CCplNamespace::_CategorizeCplApplet( IShellFolder2 *psf2Cpanel, LPCITEMIDLIST pidlItem ) { ASSERT(NULL != psf2Cpanel); ASSERT(NULL != pidlItem);
SHCOLUMNID scid = SCID_CONTROLPANELCATEGORY; VARIANT var; VariantInit(&var); DWORD dwCategoryID = 0; // The default. 0 == "other CPLs" category
HRESULT hr = psf2Cpanel->GetDetailsEx(pidlItem, &scid, &var); if (SUCCEEDED(hr)) { dwCategoryID = var.lVal; } //
// -1 is a special category ID meaning "don't categorize".
//
if (DWORD(-1) != dwCategoryID) { IUICommand *pc; hr = Create_CplUiCommandOnPidl(pidlItem, IID_IUICommand, (void **)&pc); if (SUCCEEDED(hr)) { if (-1 == m_rgCplApplets[dwCategoryID].Append(pc)) { pc->Release(); hr = E_OUTOFMEMORY; } } } VariantClear(&var); return THR(hr); }
HRESULT CPL::CplNamespace_CreateInstance( IEnumIDList *penumIDs, REFIID riid, void **ppvOut ) { ASSERT(NULL != penumIDs); ASSERT(NULL != ppvOut); ASSERT(!IsBadWritePtr(ppvOut, sizeof(*ppvOut)));
HRESULT hr = CCplNamespace::CreateInstance(penumIDs, riid, ppvOut); return THR(hr); }
HRESULT CPL::CplNamespace_GetCategoryAppletCount( ICplNamespace *pns, eCPCAT eCategory, int *pcApplets ) { ASSERT(NULL != pns); ASSERT(NULL != pcApplets); ASSERT(!IsBadWritePtr(pcApplets, sizeof(*pcApplets)));
*pcApplets = 0;
ICplCategory *pCategory; HRESULT hr = pns->GetCategory(eCategory, &pCategory); if (SUCCEEDED(hr)) { IEnumUICommand *peuic; hr = pCategory->EnumCplApplets(&peuic); if (SUCCEEDED(hr)) { IUICommand *puic; while(S_OK == (hr = peuic->Next(1, &puic, NULL))) { puic->Release(); (*pcApplets)++; } peuic->Release(); } pCategory->Release(); } return hr; }
} // namespace CPL
|