4461 lines
135 KiB
C++
4461 lines
135 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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
|