1753 lines
66 KiB
C++
1753 lines
66 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: C M D T A B L E . C P P
|
|
//
|
|
// Contents: Command-table code -- determines which menu options are
|
|
// available by the selection count, among other criteria
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: jeffspr 28 Jan 1998
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "foldinc.h" // Standard shell\folder includes
|
|
#include "foldres.h" // Folder resource IDs
|
|
#include "nsres.h" // Netshell strings
|
|
#include "cmdtable.h" // Header for this file
|
|
#include "ncperms.h" // For checking User's rights on actions/menu items
|
|
#include "cfutils.h"
|
|
#include "hnetcfg.h"
|
|
#include "lm.h"
|
|
|
|
//---[ Constants ]------------------------------------------------------------
|
|
|
|
const DWORD NCCF_ALL = 0xffffffff; // NCCF_ALL - For all Characteristics
|
|
const DWORD S_REMOVE = 2;
|
|
#define TRACESTRLEN 65535
|
|
|
|
|
|
// Active must be a subset of Visible (Opening connections folder using a CHK DLL asserts integrity of table).
|
|
// DO NOT use NCM_ and NCS_ flags in this table!!! You should use NBM_ and NBS_ flags over here.
|
|
COMMANDENTRY g_cteCommandMatrix[] =
|
|
{
|
|
//iCommandId dwDefaultPriority dwFlags HrEnableDisableCB HrCustomMenuStringCB
|
|
// | | dwValidWhen | | |
|
|
// | | | | dwMediaTypeVisible | | dwMediaTypeActive
|
|
// | | | | dwStatusVisible | | dwStatusActive
|
|
// | | | | dwCharacteristicsVisible | | dwCharacteristicsActive
|
|
// | | | | (VISIBLE) | | (ACTIVE... (NOT REMOVED))
|
|
// v v v v | v v |
|
|
// v v
|
|
{ CMIDM_HOMENET_WIZARD, 5, NCWHEN_ANYSELECT, NB_REMOVE_TOPLEVEL_ITEM,HrIsHomeNewWizardSupported, NULL,
|
|
NBM_HNW_WIZARD, NBM_HNW_WIZARD, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_NET_TROUBLESHOOT, 5, NCWHEN_TOPLEVEL, NB_REMOVE_TOPLEVEL_ITEM,HrIsTroubleShootSupported, NULL,
|
|
NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
|
|
NBS_NONE, NBS_NONE, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_CONMENU_ADVANCED_CONFIG,
|
|
5, NCWHEN_TOPLEVEL, NB_NO_FLAGS, NULL, NULL,
|
|
NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
|
|
NBS_NONE, NBS_NONE, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_CONMENU_DIALUP_PREFS,
|
|
5, NCWHEN_TOPLEVEL,
|
|
NB_NO_FLAGS, NULL, NULL,
|
|
NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
|
|
NBS_NONE, NBS_NONE, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_NEW_CONNECTION, 5, NCWHEN_ANYSELECT, NB_VERB, HrIsNCWSupported, NULL,
|
|
NBM_MNC_WIZARD, NBM_MNC_WIZARD, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_CONNECT, 3, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
|
|
NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, // Media Type
|
|
NBS_HW_ISSUE | NBS_DISCONNECTED | NBS_CONNECTING, NBS_DISCONNECTED, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_DISCONNECT, 0, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
|
|
NBM_SHAREDACCESSHOST_RAS|NBM_ISRASTYPE,NBM_SHAREDACCESSHOST_RAS|NBM_ISRASTYPE, // Media Type
|
|
NBS_IS_CONNECTED | NBS_DISCONNECTING, NBS_IS_CONNECTED, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_ENABLE, 3, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
|
|
NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE,NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE, // Media Type
|
|
NBS_HW_ISSUE | NBS_DISCONNECTED | NBS_CONNECTING, NBS_DISCONNECTED, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_DISABLE, 0, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
|
|
NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE,NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE, // Media Type
|
|
NBS_DISCONNECTING | NBS_IS_CONNECTED | NBS_MEDIA_DISCONNECTED | NBS_INVALID_ADDRESS, NBS_NOT_DISCONNECT, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_WZCDLG_SHOW, 4, NCWHEN_ONESELECT, NB_VERB, HrIsMediaWireless, NULL,
|
|
NBM_LAN, NBM_LAN, // Media Type
|
|
NBS_NOT_DISCONNECT, NBS_NOT_DISCONNECT, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_STATUS, 5, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
|
|
NBM_INCOMING | NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE, NBM_INCOMING | NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE,
|
|
NBS_ANY, NBS_IS_CONNECTED | NBS_INVALID_ADDRESS, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_FIX, 0, NCWHEN_SOMESELECT, NB_NO_FLAGS, NULL, NULL,
|
|
NBM_ISLANTYPE, NBM_ISLANTYPE, // Media Type
|
|
NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_INVALID_ADDRESS | NBS_IS_CONNECTED, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
|
|
|
|
{ CMIDM_SET_DEFAULT, 0, NCWHEN_ONESELECT, NB_NEGATE_CHAR_MATCH, NULL, NULL,
|
|
NBM_INCOMING | NBM_ISRASTYPE, NBM_INCOMING | NBM_ISRASTYPE, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_INCOMING_ONLY | NCCF_DEFAULT, NCCF_INCOMING_ONLY | NCCF_DEFAULT}, // Characteristics
|
|
|
|
{ CMIDM_UNSET_DEFAULT, 0, NCWHEN_ONESELECT, NB_NO_FLAGS, NULL, NULL,
|
|
NBM_INCOMING | NBM_ISRASTYPE, NBM_INCOMING | NBM_ISRASTYPE, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_DEFAULT, NCCF_DEFAULT}, // Characteristics
|
|
|
|
{ CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
|
|
|
|
{ CMIDM_CREATE_BRIDGE, 0, NCWHEN_ANYSELECT, NB_NO_FLAGS, HrIsBridgeSupported, NULL,
|
|
NBM_LAN, NBM_LAN, // Media Type
|
|
NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_DISCONNECTING|NBS_IS_CONNECTED|NBS_MEDIA_DISCONNECTED|NBS_INVALID_ADDRESS, // Status
|
|
NCCF_ALL, NCCF_ALL }, // Characteristics
|
|
|
|
{ CMIDM_CONMENU_CREATE_BRIDGE,0, NCWHEN_TOPLEVEL,NB_REMOVE_TOPLEVEL_ITEM,HrIsBridgeSupported, NULL,
|
|
NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
|
|
NBS_NONE, NBS_NONE, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
|
|
{ CMIDM_ADD_TO_BRIDGE, 0, NCWHEN_SOMESELECT, NB_NEGATE_CHAR_MATCH, HrIsBridgeSupported, NULL,
|
|
NBM_LAN, NBM_LAN, // Media Type
|
|
NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_DISCONNECTING|NBS_IS_CONNECTED|NBS_MEDIA_DISCONNECTED|NBS_INVALID_ADDRESS, // Status
|
|
NCCF_BRIDGED | NCCF_FIREWALLED | NCCF_SHARED, NCCF_BRIDGED | NCCF_FIREWALLED | NCCF_SHARED }, // Characteristics
|
|
|
|
{ CMIDM_REMOVE_FROM_BRIDGE, 0, NCWHEN_SOMESELECT,NB_NO_FLAGS, HrIsBridgeSupported, NULL,
|
|
NBM_LAN, NBM_LAN, // Media Type
|
|
NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_DISCONNECTING|NBS_IS_CONNECTED|NBS_MEDIA_DISCONNECTED|NBS_INVALID_ADDRESS, // Status
|
|
NCCF_BRIDGED, NCCF_BRIDGED }, // Characteristics
|
|
|
|
{ CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
|
|
|
|
{ CMIDM_CREATE_COPY, 0, NCWHEN_ONESELECT, NB_NEGATE_VIS_CHAR_MATCH, NULL, NULL,
|
|
NBM_INCOMING | NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, NBM_INCOMING | NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_INCOMING_ONLY, NCCF_ALLOW_DUPLICATION}, // Characteristics
|
|
|
|
{ CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
|
|
|
|
{ CMIDM_CREATE_SHORTCUT, 0, NCWHEN_ONESELECT, NB_NEGATE_CHAR_MATCH, NULL, NULL,
|
|
NBM_ANY, NBM_ANY, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_INCOMING_ONLY, NCCF_INCOMING_ONLY}, // Characteristics
|
|
|
|
{ CMIDM_DELETE, 0, NCWHEN_SOMESELECT, NB_NO_FLAGS, NULL, NULL,
|
|
NBM_NOTWIZARD, NBM_NOTWIZARD, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_ALL, NCCF_ALLOW_REMOVAL}, // Characteristics
|
|
|
|
|
|
{ CMIDM_RENAME, 0, NCWHEN_ONESELECT, NB_NO_FLAGS, HrCanRenameConnection, NULL,
|
|
NBM_NOTWIZARD, NBM_NOTWIZARD, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_ALL, NCCF_ALLOW_RENAME}, // Characteristics
|
|
|
|
{ CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
|
|
|
|
{ CMIDM_PROPERTIES, 2, NCWHEN_ONESELECT, NB_NO_FLAGS, HrCanShowProperties, NULL,
|
|
NBM_INCOMING|NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE, NBM_INCOMING|NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE, // Media Type
|
|
NBS_ANY, NBS_ANY, // Status
|
|
NCCF_ALL, NCCF_ALL}, // Characteristics
|
|
};
|
|
|
|
// What is the difference between NCCF_INCOMING_ONLY, ~NCCF_INCOMING_ONLY and NCCF_INCOMING_ONLY + NB_NEGATE_CHAR_MATCH?
|
|
// NCCF_INCOMING_ONLY | NCCF_ALLOW_REMOVAL means: NCCF_INCOMING_ONLY or NCCF_ALLOW_REMOVAL or BOTH should be set.
|
|
// ~NCCF_INCOMING_ONLY means: One or flag (irrespective of NCCF_INCOMING_ONLY flag) should be set.
|
|
// NB_NEGATE_CHAR_MATCH + NCCF_INCOMING_ONLY means: Check that NCCF_INCOMING_ONLY is not set.
|
|
|
|
const DWORD g_cteCommandMatrixCount = celems(g_cteCommandMatrix);
|
|
|
|
COMMANDPERMISSIONSENTRY g_cteCommandPermissionsMatrix[] =
|
|
{
|
|
{ CMIDM_NEW_CONNECTION, NBM_ANY, NCCF_ALL, NB_TOPLEVEL_PERM | NB_REMOVE_IF_NOT_MATCH,NBPERM_NewConnectionWizard, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_CONNECT, NBM_ISRASTYPE, NCCF_ALL, NB_NO_FLAGS, NBPERM_RasConnect, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_CONNECT, NBM_SHAREDACCESSHOST_RAS, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
|
|
|
|
{ CMIDM_DISCONNECT, NBM_ISRASTYPE, NCCF_INCOMING_ONLY, NB_NEGATE_CHAR_MATCH,NBPERM_RasConnect, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_DISCONNECT, NBM_ISRASTYPE, NCCF_INCOMING_ONLY, NB_NO_FLAGS, NBPERM_RasConnect, APPLY_TO_ADMIN },
|
|
{ CMIDM_DISCONNECT, NBM_SHAREDACCESSHOST_RAS, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_ENABLE, NBM_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_LanConnect, APPLY_TO_ALL_USERS },
|
|
|
|
{ CMIDM_ENABLE, NBM_SHAREDACCESSHOST_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_ENABLE, NBM_BRIDGE, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
|
|
{ CMIDM_DISABLE, NBM_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_LanConnect, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_DISABLE, NBM_SHAREDACCESSHOST_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_DISABLE, NBM_BRIDGE, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
|
|
|
|
{ CMIDM_STATUS, NBM_ANY, NCCF_INCOMING_ONLY, NB_NEGATE_CHAR_MATCH,NBPERM_Statistics, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_STATUS, NBM_ANY, NCCF_INCOMING_ONLY, NB_NO_FLAGS, NBPERM_Statistics, APPLY_TO_ADMIN },
|
|
|
|
{ CMIDM_CREATE_BRIDGE, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
|
|
{ CMIDM_ADD_TO_BRIDGE, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
|
|
{ CMIDM_REMOVE_FROM_BRIDGE, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
|
|
|
|
{ CMIDM_CREATE_COPY, NBM_ANY, NCCF_ALL_USERS, NB_NO_FLAGS, NBPERM_NewConnectionWizard | NBPERM_RasAllUserProperties, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_CREATE_COPY, NBM_ANY, NCCF_ALL_USERS, NB_NEGATE_CHAR_MATCH,NBPERM_NewConnectionWizard, APPLY_TO_ALL_USERS },
|
|
|
|
{ CMIDM_FIX, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_Repair, APPLY_TO_POWERUSERSPLUS },
|
|
|
|
{ CMIDM_DELETE, NBM_ANY, NCCF_ALL_USERS, NB_NO_FLAGS, NBPERM_DeleteConnection | NBPERM_DeleteAllUserConnection, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_DELETE, NBM_ANY, NCCF_ALL_USERS, NB_NEGATE_CHAR_MATCH,NBPERM_DeleteConnection, APPLY_TO_ALL_USERS },
|
|
|
|
{ CMIDM_SET_DEFAULT, NBM_INCOMING |
|
|
NBM_ISRASTYPE, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_OPS_OR_ADMIN },
|
|
{ CMIDM_UNSET_DEFAULT, NBM_INCOMING |
|
|
NBM_ISRASTYPE, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_OPS_OR_ADMIN },
|
|
|
|
{ CMIDM_CONMENU_ADVANCED_CONFIG,
|
|
NBM_ANY, NCCF_ALL_USERS, NB_TOPLEVEL_PERM, NBPERM_AdvancedSettings, APPLY_TO_ADMIN },
|
|
|
|
{ CMIDM_CONMENU_DIALUP_PREFS,
|
|
NBM_ANY, NCCF_ALL_USERS, NB_TOPLEVEL_PERM, NBPERM_DialupPrefs, APPLY_TO_ALL_USERS },
|
|
|
|
{ CMIDM_PROPERTIES, NBM_INCOMING, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ADMIN },
|
|
{ CMIDM_PROPERTIES, NBM_ISRASTYPE, NCCF_ALL_USERS, NB_NEGATE_CHAR_MATCH,NBPERM_RasMyProperties, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_PROPERTIES, NBM_ISRASTYPE, NCCF_ALL_USERS, NB_NO_FLAGS, NBPERM_RasAllUserProperties, APPLY_TO_ALL_USERS },
|
|
{ CMIDM_PROPERTIES, NBM_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_LanProperties, APPLY_TO_ALL_USERS }
|
|
};
|
|
|
|
const DWORD g_cteCommandPermissionsMatrixCount = celems(g_cteCommandPermissionsMatrix);
|
|
|
|
SFVCOMMANDMAP g_cteSFVCommandMap[] =
|
|
{
|
|
{ SFVIDM_FILE_DELETE, CMIDM_DELETE},
|
|
{ SFVIDM_FILE_LINK, CMIDM_CREATE_SHORTCUT},
|
|
{ SFVIDM_FILE_PROPERTIES, CMIDM_PROPERTIES},
|
|
{ SFVIDM_FILE_RENAME, CMIDM_RENAME}
|
|
};
|
|
|
|
const DWORD g_cteSFVCommandMapCount = celems(g_cteSFVCommandMap);
|
|
|
|
CMDCHKENTRY g_cceFolderChecks[] =
|
|
{
|
|
// command id
|
|
// currently checked
|
|
// | new check state
|
|
// | |
|
|
// v v
|
|
{ CMIDM_CONMENU_OPERATOR_ASSIST, false, false }
|
|
};
|
|
|
|
const DWORD g_nFolderCheckCount = celems(g_cceFolderChecks);
|
|
|
|
inline DWORD dwNegateIf(DWORD dwInput, DWORD dwFlags, DWORD dwNegateCondition)
|
|
{
|
|
if (dwFlags & dwNegateCondition)
|
|
{
|
|
return ~dwInput;
|
|
}
|
|
else
|
|
{
|
|
return dwInput;
|
|
}
|
|
}
|
|
|
|
inline BOOL bContains(DWORD dwContainee, DWORD dwContainer, DWORD dwFlags, DWORD dwContaineeNegateCondition, DWORD dwContainerNegateCondition)
|
|
{
|
|
dwContainer = dwNegateIf(dwContainer, dwFlags, dwContainerNegateCondition);
|
|
dwContainee = dwNegateIf(dwContainee, dwFlags, dwContaineeNegateCondition);
|
|
|
|
if ( (dwContainee & dwContainer) != dwContainee)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrAssertIntegrityAgainstOldMatrix
|
|
//
|
|
// Purpose: Asserts the internal integrity of the Command Matrix
|
|
// Currently checks for:
|
|
// 1. No duplicate CMDIDs
|
|
// 2. Each NCWHEN flag at least specified NCWHEN_ONESELECT
|
|
//
|
|
// Arguments:
|
|
// none
|
|
//
|
|
// Returns:
|
|
// S_OK is succeeded
|
|
// E_FAIL if not
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes: Asserts on failure
|
|
//
|
|
HRESULT HrAssertCommandMatrixIntegrity()
|
|
{
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
LPSTR szErr = new CHAR[TRACESTRLEN];
|
|
for (DWORD x = 0; x < g_cteCommandMatrixCount; x++)
|
|
{
|
|
// Check that there isn't another entry with the same CommandID and Media Type.
|
|
const COMMANDENTRY& cte = g_cteCommandMatrix[x];
|
|
if (CMIDM_SEPARATOR == cte.iCommandId)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (DWORD y = x + 1; y < g_cteCommandMatrixCount; y++)
|
|
{
|
|
const COMMANDENTRY& ctecmp = g_cteCommandMatrix[y];
|
|
if (cte.iCommandId == ctecmp.iCommandId)
|
|
{
|
|
sprintf(szErr, "Multiple lines (%d and %d) in the COMMANDENTRY table describe the same CmdID", x+1, y+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
if ( !bContains(cte.dwCharacteristicsActive, cte.dwCharacteristicsVisible, cte.dwFlags, NB_NEGATE_ACT_CHAR_MATCH, NB_NEGATE_VIS_CHAR_MATCH) )
|
|
{
|
|
sprintf(szErr, "Row %d. ACTIVE flags not a subset of VISIBLE flags for Characteristics? ", x+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
if ( !bContains(cte.dwStatusActive, cte.dwStatusVisible, cte.dwFlags, NB_NEGATE_ACT_NBS_MATCH, NB_NEGATE_VIS_NBS_MATCH) )
|
|
{
|
|
sprintf(szErr, "Row %d. ACTIVE flags not a subset of VISIBLE flags for Status... did you use NCS_ instead of NBM_? ", x+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
if ( !bContains(cte.dwMediaTypeActive, cte.dwMediaTypeVisible, cte.dwFlags, NB_NEGATE_ACT_NBM_MATCH, NB_NEGATE_VIS_NBM_MATCH) )
|
|
{
|
|
sprintf(szErr, "Row %d. ACTIVE flags not a subset of VISIBLE flags for MediaType... did you use NCM_ instead of NBM_? ", x+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
// Assert the permissions table
|
|
for (x = 0; x < g_cteCommandPermissionsMatrixCount; x++)
|
|
{
|
|
const COMMANDPERMISSIONSENTRY cpe = g_cteCommandPermissionsMatrix[x];
|
|
|
|
// Check that each CMD entry has a corresponding entry in the Command Table
|
|
BOOL bFound = FALSE;
|
|
for (DWORD y = 0; y < g_cteCommandMatrixCount; y++)
|
|
{
|
|
const COMMANDENTRY& ctecmp = g_cteCommandMatrix[y];
|
|
|
|
if (cpe.iCommandId == ctecmp.iCommandId)
|
|
{
|
|
bFound = TRUE;
|
|
if ( (cpe.dwMediaType != NBM_ANY) &&
|
|
((cpe.dwMediaType & ctecmp.dwMediaTypeActive) != cpe.dwMediaType) )
|
|
{
|
|
sprintf(szErr, "A permission has been specified in the Permissions table (row %d) for a MediaType that is not active in the Command Table (row %d)... did you use NCM_ instead of NBM_?", x+1, y+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
// if ( (cpe.dwCharacteristicsActive != NCCF_ALL) &&
|
|
// ((cpe.dwCharacteristicsActive & ctecmp.dwCharacteristicsActive) != cpe.dwCharacteristicsActive) )
|
|
// {
|
|
// sprintf(szErr, "A permission has been specified in the Permissions table (row %d) for a Characteristics that is not active in the Command Table (row %d)", x+1, y+1);
|
|
// AssertSz(FALSE, szErr);
|
|
// hr = E_FAIL;
|
|
// }
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
sprintf(szErr, "An entry has been found in the Permissions table (row %d) without a corresponding CMDID entry in the Command Table", x+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
// Check that no CmdId/MediaType/Characteristics has been duplicated
|
|
for (y = x + 1; y < g_cteCommandPermissionsMatrixCount; y++)
|
|
{
|
|
const COMMANDPERMISSIONSENTRY& cpecmp = g_cteCommandPermissionsMatrix[y];
|
|
if ( (cpe.iCommandId == cpecmp.iCommandId) &&
|
|
(dwNegateIf(cpe.dwMediaType, cpe.dwFlags, NB_NEGATE_NBM_MATCH) &
|
|
dwNegateIf(cpecmp.dwMediaType, cpecmp.dwFlags, NB_NEGATE_NBM_MATCH)) &&
|
|
(dwNegateIf(cpe.dwCharacteristicsActive, cpe.dwFlags, NB_NEGATE_CHAR_MATCH) &
|
|
dwNegateIf(cpecmp.dwCharacteristicsActive, cpecmp.dwFlags, NB_NEGATE_CHAR_MATCH)) )
|
|
{
|
|
sprintf(szErr, "Multiple lines (%d and %d) in the COMMANDENTRY table describe the same CmdID/MediaType/Characteristics combo", x+1, y+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
if (! ((APPLY_TO_NETCONFIGOPS & cpe.ncpAppliesTo) ||
|
|
(APPLY_TO_USER & cpe.ncpAppliesTo) ||
|
|
(APPLY_TO_ADMIN & cpe.ncpAppliesTo) ||
|
|
(APPLY_TO_POWERUSERS & cpe.ncpAppliesTo) ))
|
|
{
|
|
sprintf(szErr, "Lines (%d) in the Permissionstable - permissions must apply to someone", x+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
// !!(A & B) != !!(A & C) means: If either B or C is set in A, both B and C must be set (or neither). I hope...
|
|
// kill me... kill me now.
|
|
if ((!!(cpe.dwFlags & NB_NEGATE_VIS_NBM_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_NBM_MATCH)) ||
|
|
(!!(cpe.dwFlags & NB_NEGATE_VIS_NBS_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_NBS_MATCH)) ||
|
|
(!!(cpe.dwFlags & NB_NEGATE_VIS_CHAR_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_CHAR_MATCH)) ||
|
|
(!!(cpe.dwFlags & NB_NEGATE_VIS_PERMS_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_PERMS_MATCH)) )
|
|
{
|
|
sprintf(szErr, "Lines (%d) in the Permissionstable should use NB_NEGATE_xxx instead of NB_NEGATE_VIS_xxx or NB_NEGATE_ACT_xxx ", x+1);
|
|
AssertSz(FALSE, szErr);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
delete[] szErr;
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrAssertMenuStructuresValid
|
|
//
|
|
// Purpose: Runs various asserts to make sure the menu structures are intact
|
|
// Called on NetShell startup
|
|
//
|
|
// Arguments:
|
|
// [in] hwndOwner Owner window
|
|
//
|
|
// Returns:
|
|
// S_OK is succeeded
|
|
// E_FAIL if not
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes: Asserts on failure
|
|
//
|
|
HRESULT HrAssertMenuStructuresValid(HWND hwndOwner)
|
|
{
|
|
#ifdef DBG
|
|
static fBeenHereDoneThat = FALSE;
|
|
|
|
if (fBeenHereDoneThat)
|
|
{
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
fBeenHereDoneThat = TRUE;
|
|
}
|
|
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
HRESULT hr;
|
|
hr = HrAssertCommandMatrixIntegrity();
|
|
|
|
return hr;
|
|
#else
|
|
return S_OK;
|
|
#endif
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: AdjustNCCS
|
|
//
|
|
// Purpose: Up-adjusts an NCCS_STATE flag. Will move ENABLED to DISABLED,
|
|
// and DISABLED to REMOVE but not backwards.
|
|
//
|
|
// Arguments:
|
|
// [in out] nccsCurrent NCCS to be adjusted
|
|
// [in] nccsNew New state
|
|
//
|
|
// Returns:
|
|
// none
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
inline void AdjustNCCS(OUT IN NCCS_STATE& nccsCurrent, IN NCCS_STATE nccsNew)
|
|
{
|
|
if (nccsNew > nccsCurrent)
|
|
{
|
|
nccsCurrent = nccsNew;
|
|
}
|
|
}
|
|
|
|
inline BOOL fMatchFlags(IN DWORD dwFlagsMask, IN DWORD dwFlagsTest, IN DWORD dwNegateFlagMask, IN DWORD dwNegateFlagTest)
|
|
{
|
|
bool bMatch = FALSE;
|
|
|
|
if ( (0xffffffff == dwFlagsTest) || // Means always succeed.
|
|
(dwFlagsMask & dwFlagsTest) )
|
|
{
|
|
bMatch = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bMatch = FALSE;
|
|
}
|
|
|
|
if ( (dwNegateFlagMask & dwNegateFlagTest) == dwNegateFlagTest) // Do a negative compare
|
|
{
|
|
return !bMatch;
|
|
}
|
|
else
|
|
{
|
|
return bMatch;
|
|
}
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrGetCommandStateFromCMDTABLEEntry
|
|
//
|
|
// Purpose: Get the command state for a given Connection Folder Entry,
|
|
// given the Command Table Entry entry that should be used.
|
|
//
|
|
// Arguments:
|
|
// [in] cfe Connection Folder Entry
|
|
// [in] cte Command Table Entry
|
|
// [in] fMultiSelect Was this part of a multi-selection?
|
|
// [out] nccs State that the item should be (NCCS_ENABLED/NCCS_DISABLED/NCCS_NOTSHOWN)
|
|
//
|
|
// Returns:
|
|
// none
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes: This function uses Cached Permissions. YOU MUST CALL RefreshAllPermission before calling this function.
|
|
//
|
|
HRESULT HrGetCommandStateFromCMDTABLEEntry(IN const CConFoldEntry& cfe, IN const COMMANDENTRY& cte, IN BOOL fMultiSelect, OUT NCCS_STATE& nccs, OUT LPDWORD pdwResourceId)
|
|
{
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
Assert(pdwResourceId);
|
|
|
|
HRESULT hr = S_OK;
|
|
nccs = NCCS_ENABLED;
|
|
|
|
DWORD dwNCMbm = (1 << cfe.GetNetConMediaType()); // Convert to bitmask
|
|
|
|
// If we're a wizard, add as Wizard media type.
|
|
if (cfe.GetWizard() == WIZARD_MNC)
|
|
{
|
|
dwNCMbm |= NBM_MNC_WIZARD;
|
|
dwNCMbm &= ~NBM_INCOMING; // clear the INCOMINGCONNECTIONS flag (old NCM_NONE) if we're a wizard.
|
|
}
|
|
else if (cfe.GetWizard() == WIZARD_HNW)
|
|
{
|
|
dwNCMbm |= NBM_HNW_WIZARD;
|
|
dwNCMbm &= ~NBM_INCOMING; // clear the INCOMINGCONNECTIONS flag (old NCM_NONE) if we're a wizard.
|
|
}
|
|
|
|
DWORD dwNCSbm = (1 << cfe.GetNetConStatus()); // Convert to bitmask
|
|
DWORD dwNCCF = cfe.GetCharacteristics(); // Already a bitmask
|
|
|
|
// Check if the command can participate in multi-select
|
|
if ( fMultiSelect &&
|
|
!(cte.dwValidWhen & NCWHEN_MULTISELECT) )
|
|
{
|
|
AdjustNCCS(nccs, NCCS_DISABLED);
|
|
}
|
|
|
|
// Check if the command should be visible
|
|
if (!((fMatchFlags(dwNCMbm, cte.dwMediaTypeVisible, cte.dwFlags, NB_NEGATE_VIS_NBM_MATCH)) &&
|
|
(fMatchFlags(dwNCSbm, cte.dwStatusVisible, cte.dwFlags, NB_NEGATE_VIS_NBS_MATCH)) &&
|
|
(fMatchFlags(dwNCCF , cte.dwCharacteristicsVisible,cte.dwFlags, NB_NEGATE_VIS_CHAR_MATCH)) ))
|
|
{
|
|
AdjustNCCS(nccs, NCCS_NOTSHOWN);
|
|
}
|
|
|
|
// Check if the command should be grayed out
|
|
if (!((fMatchFlags(dwNCMbm, cte.dwMediaTypeActive, cte.dwFlags, NB_NEGATE_ACT_NBM_MATCH)) &&
|
|
(fMatchFlags(dwNCSbm, cte.dwStatusActive, cte.dwFlags, NB_NEGATE_ACT_NBS_MATCH)) &&
|
|
(fMatchFlags(dwNCCF , cte.dwCharacteristicsActive, cte.dwFlags, NB_NEGATE_ACT_CHAR_MATCH)) ))
|
|
{
|
|
AdjustNCCS(nccs, NCCS_DISABLED);
|
|
}
|
|
|
|
// Check if the command should be grayed out based on permissions
|
|
for (DWORD x = 0; nccs == NCCS_ENABLED, x < g_cteCommandPermissionsMatrixCount; x++)// Permissions won't affect NOT_SHOWN or DISABLED
|
|
{
|
|
const COMMANDPERMISSIONSENTRY cpe = g_cteCommandPermissionsMatrix[x];
|
|
|
|
if ( (cpe.iCommandId == cte.iCommandId) &&
|
|
(fMatchFlags(dwNCMbm, cpe.dwMediaType, cpe.dwFlags, NB_NEGATE_NBM_MATCH)) &&
|
|
(fMatchFlags(dwNCCF, cpe.dwCharacteristicsActive, cpe.dwFlags, NB_NEGATE_CHAR_MATCH)) )
|
|
{
|
|
for (DWORD dwPerm = 0; dwPerm < sizeof(DWORD)*8; dwPerm++)
|
|
{
|
|
if (cpe.dwPermissionsActive & (1 << static_cast<DWORD64>(dwPerm)) )
|
|
{
|
|
if (!FHasPermissionFromCache(dwPerm))
|
|
{
|
|
if (cpe.dwFlags & NB_REMOVE_IF_NOT_MATCH)
|
|
{
|
|
AdjustNCCS(nccs, NCCS_NOTSHOWN);
|
|
}
|
|
else
|
|
{
|
|
AdjustNCCS(nccs, NCCS_DISABLED);
|
|
}
|
|
break; // will break anyway.
|
|
}
|
|
}
|
|
}
|
|
|
|
if (APPLY_TO_USER & cpe.ncpAppliesTo)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( (APPLY_TO_POWERUSERS & cpe.ncpAppliesTo) && FIsUserPowerUser() )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( (APPLY_TO_NETCONFIGOPS & cpe.ncpAppliesTo) && FIsUserNetworkConfigOps() )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( (APPLY_TO_ADMIN & cpe.ncpAppliesTo) && FIsUserAdmin())
|
|
{
|
|
break;
|
|
}
|
|
|
|
// At this point all group access checks failed, so disable the connection.
|
|
AdjustNCCS(nccs, NCCS_DISABLED);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check for callback
|
|
if ( (nccs != NCCS_NOTSHOWN) &&
|
|
(cte.pfnHrEnableDisableCB) )
|
|
{
|
|
HRESULT hrTmp;
|
|
NCCS_STATE nccsTemp;
|
|
hrTmp = (*cte.pfnHrEnableDisableCB)(cfe, fMultiSelect, cte.iCommandId, nccsTemp);
|
|
if (S_OK == hrTmp)
|
|
{
|
|
AdjustNCCS(nccs, nccsTemp);
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hrTmp))
|
|
{
|
|
AdjustNCCS(nccs, NCCS_NOTSHOWN);
|
|
}
|
|
} // If the function returns S_FALSE it's an indication it didn't change the state.
|
|
}
|
|
|
|
// Check for Resource String callback:
|
|
if ( (nccs != NCCS_NOTSHOWN) && // What's the point?
|
|
(0 == *pdwResourceId) && // Must not already have a resource Id
|
|
(cte.pfnHrCustomMenuStringCB) )
|
|
{
|
|
HRESULT hrTmp;
|
|
DWORD dwResourceIdTmp = *pdwResourceId;
|
|
hrTmp = (*cte.pfnHrCustomMenuStringCB)(cfe, cte.iCommandId, &dwResourceIdTmp);
|
|
if (S_OK == hr)
|
|
{
|
|
*pdwResourceId = dwResourceIdTmp;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrGetCommandState
|
|
//
|
|
// Purpose: Get the command state for a given Connection Folder Entry,
|
|
// given the Command ID.
|
|
//
|
|
// Arguments:
|
|
// [in] cfpl List (0 or more) of PIDLs that are selected
|
|
// [in] dwCmdID Command ID
|
|
// [out] nccs State that the item should be (NCCS_ENABLED/NCCS_DISABLED/NCCS_NOTSHOWN)
|
|
//
|
|
// Returns:
|
|
// none
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrGetCommandState(IN const PCONFOLDPIDLVEC& cfpl, IN const DWORD dwCmdID, OUT NCCS_STATE& nccs, OUT LPDWORD pdwResourceId, IN DWORD cteHint, IN DWORD dwOverrideFlag)
|
|
{
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
Assert(pdwResourceId);
|
|
if (!pdwResourceId)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
|
|
RefreshAllPermission();
|
|
|
|
HRESULT hr = S_OK;
|
|
BOOL bFound = FALSE;
|
|
DWORD dwNumItems = cfpl.size();
|
|
*pdwResourceId = 0;
|
|
|
|
if ( dwOverrideFlag & NB_FLAG_ON_TOPMENU )
|
|
{
|
|
for (DWORD x = 0; x < g_cteCommandMatrixCount; x++)
|
|
{
|
|
if ( (g_cteCommandMatrix[x].iCommandId == dwCmdID) )
|
|
{
|
|
bFound = TRUE;
|
|
|
|
const COMMANDENTRY& cte = g_cteCommandMatrix[x];
|
|
if ((cte.dwValidWhen == NCWHEN_TOPLEVEL) || // Toplevel-ONLY menu (doesn't matter if items).
|
|
((cte.dwValidWhen & NCWHEN_TOPLEVEL) &&
|
|
(!dwNumItems || (cte.dwValidWhen & NCWHEN_TOPLEVEL_DISREGARD_ITEM)) ) )
|
|
{ // Must be marked to allow incompatible selection,
|
|
nccs = NCCS_ENABLED; // Otherwise, we'll do the item check (below).
|
|
|
|
// Check for permissions
|
|
for (DWORD x = 0; nccs == NCCS_ENABLED, x < g_cteCommandPermissionsMatrixCount; x++)// Permissions won't affect NOT_SHOWN or DISABLED
|
|
{
|
|
const COMMANDPERMISSIONSENTRY cpe = g_cteCommandPermissionsMatrix[x];
|
|
|
|
if ( (cpe.iCommandId == cte.iCommandId) &&
|
|
(cpe.dwFlags & NB_TOPLEVEL_PERM) )
|
|
{
|
|
for (DWORD dwPerm = 0; dwPerm < sizeof(DWORD)*8; dwPerm++)
|
|
{
|
|
if (cpe.dwPermissionsActive & (1 << static_cast<DWORD64>(dwPerm)) )
|
|
{
|
|
if (!FHasPermissionFromCache(dwPerm))
|
|
{
|
|
if (cpe.dwFlags & NB_REMOVE_IF_NOT_MATCH)
|
|
{
|
|
AdjustNCCS(nccs, NCCS_NOTSHOWN);
|
|
}
|
|
else
|
|
{
|
|
AdjustNCCS(nccs, NCCS_DISABLED);
|
|
}
|
|
break; // will break anyway.
|
|
}
|
|
}
|
|
}
|
|
|
|
if (APPLY_TO_USER & cpe.ncpAppliesTo)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( (APPLY_TO_NETCONFIGOPS & cpe.ncpAppliesTo) && FIsUserNetworkConfigOps() )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( (APPLY_TO_ADMIN & cpe.ncpAppliesTo) && FIsUserAdmin())
|
|
{
|
|
break;
|
|
}
|
|
|
|
// At this point all group access checks failed, so disable the connection.
|
|
AdjustNCCS(nccs, NCCS_DISABLED);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// Check for callback
|
|
if (cte.pfnHrEnableDisableCB)
|
|
{
|
|
HRESULT hrTmp;
|
|
NCCS_STATE nccsTemp;
|
|
CONFOLDENTRY cfe;
|
|
cfe.clear();
|
|
|
|
if (dwNumItems > 0)
|
|
{
|
|
hrTmp = cfpl[0].ConvertToConFoldEntry(cfe);
|
|
if (FAILED(hrTmp))
|
|
{
|
|
cfe.clear();
|
|
}
|
|
}
|
|
|
|
hrTmp = (*cte.pfnHrEnableDisableCB)(cfe, dwNumItems > 1, cte.iCommandId, nccsTemp);
|
|
if (S_OK == hrTmp)
|
|
{
|
|
AdjustNCCS(nccs, nccsTemp);
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hrTmp))
|
|
{
|
|
AdjustNCCS(nccs, NCCS_NOTSHOWN);
|
|
}
|
|
} // If the function returns S_FALSE it's an indication it didn't change the state.
|
|
}
|
|
|
|
if (!(NB_REMOVE_TOPLEVEL_ITEM & cte.dwFlags))
|
|
{
|
|
if (nccs == NCCS_NOTSHOWN)
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
break; // we won't find another CMDID
|
|
}
|
|
}
|
|
|
|
if (!dwNumItems)
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
if (bFound)
|
|
{
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return E_FILE_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
|
|
AssertSz(dwNumItems, "You don't have any items selected, but you're not a top-level menu... how come?");
|
|
|
|
bFound = FALSE;
|
|
nccs = NCCS_ENABLED;
|
|
|
|
// This will effectively loop through all the selected PIDLs and apply the strictest
|
|
// nccs that applies to everything.
|
|
|
|
for (PCONFOLDPIDLVEC::const_iterator cfp = cfpl.begin(); cfp != cfpl.end(); cfp++)
|
|
{
|
|
CONFOLDENTRY cfe;
|
|
hr = cfp->ConvertToConFoldEntry(cfe);
|
|
if (FAILED(hr))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
DWORD dwPos = 0xffffffff;
|
|
|
|
// This is a O(n^(2+)) algorithm when called from HrBuildMenu.
|
|
// We pass a hint to check if we can quickly find the cte.
|
|
if ( (cteHint != 0xffffffff) &&
|
|
(g_cteCommandMatrix[cteHint].iCommandId == dwCmdID) )
|
|
{
|
|
dwPos = cteHint;
|
|
}
|
|
|
|
if (dwPos == 0xffffffff)
|
|
{
|
|
for (DWORD x = 0; x < g_cteCommandMatrixCount && SUCCEEDED(hr); x++)
|
|
{
|
|
if (g_cteCommandMatrix[x].iCommandId == dwCmdID)
|
|
{
|
|
dwPos = x;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dwPos == 0xffffffff)
|
|
{
|
|
return E_FILE_NOT_FOUND;
|
|
}
|
|
else
|
|
{
|
|
bFound = TRUE;
|
|
|
|
NCCS_STATE nccsTmp;
|
|
hr = HrGetCommandStateFromCMDTABLEEntry(cfe, g_cteCommandMatrix[dwPos], dwNumItems != 1, nccsTmp, pdwResourceId);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
AdjustNCCS(nccs, nccsTmp);
|
|
|
|
if ( (dwOverrideFlag & NB_FLAG_ON_TOPMENU) &&
|
|
(!(NB_REMOVE_TOPLEVEL_ITEM & g_cteCommandMatrix[dwPos].dwFlags)) &&
|
|
(nccs == NCCS_NOTSHOWN) )
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
return E_FILE_NOT_FOUND;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrGetCheckState
|
|
//
|
|
// Purpose: Get the check state for a given Connection Folder Entry,
|
|
// given the Command ID.
|
|
//
|
|
// Arguments:
|
|
// [in] cfpl List (0 or more) of PIDLs that are selected
|
|
// [in] dwCmdID Command ID
|
|
// [out] nccs State that the item should be (NCCS_CHECKED/NCCS_UNCHECKED)
|
|
//
|
|
// Returns:
|
|
// HRESULT
|
|
//
|
|
// Author: deonb 7 Mar 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrGetCheckState(IN const PCONFOLDPIDLVEC& cfpl, IN const DWORD dwCmdID, OUT NCCS_CHECKED_STATE& nccs)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
DWORD dwLoop = 0;
|
|
|
|
nccs = NCCS_UNCHECKED;
|
|
|
|
for (; dwLoop < g_nFolderCheckCount; dwLoop++)
|
|
{
|
|
if (dwCmdID == g_cceFolderChecks[dwLoop].iCommandId)
|
|
{
|
|
switch(g_cceFolderChecks[dwLoop].iCommandId)
|
|
{
|
|
case CMIDM_CONMENU_OPERATOR_ASSIST:
|
|
hr = S_OK;
|
|
if (g_fOperatorAssistEnabled)
|
|
{
|
|
nccs = NCCS_CHECKED;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: NCCMDFromSFV
|
|
//
|
|
// Purpose: Return a NetShell CMDID for Shell Internal IDs
|
|
//
|
|
// Arguments:
|
|
// [in] iCmdID CMDID to map
|
|
//
|
|
// Returns:
|
|
// Returns iCmdID if not shell message, or a iCmdID mapping
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
int NCCMDFromSFV(int iCmdID, DWORD idCmdFirst)
|
|
{
|
|
for (int x = 0; x < g_cteSFVCommandMapCount; x++)
|
|
{
|
|
if (g_cteSFVCommandMap[x].iSFVCommandId == iCmdID)
|
|
{
|
|
return g_cteSFVCommandMap[x].iCommandId + idCmdFirst;
|
|
}
|
|
}
|
|
return iCmdID;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrUpdateMenuItemChecks
|
|
//
|
|
// Purpose: Walk through the list of checkmark-able commands and check if
|
|
// applicable.
|
|
//
|
|
// Arguments:
|
|
// None
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: deonb 7 Mar 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrUpdateMenuItemChecks(IN PCONFOLDPIDLVEC& cfpl, IN OUT HMENU hMenu, IN DWORD idCmdFirst)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
DWORD dwLoop = 0;
|
|
|
|
Assert(hMenu)
|
|
if (!hMenu)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
int cMenuItems = GetMenuItemCount(hMenu);
|
|
|
|
for (int x = 0; x < cMenuItems; x++)
|
|
{
|
|
UINT nMenuID = GetMenuItemID(hMenu, x);
|
|
|
|
NCCS_CHECKED_STATE nccs;
|
|
DWORD dwCustomResourceId = 0;
|
|
DWORD dwCmdId = NCCMDFromSFV(nMenuID, idCmdFirst) - idCmdFirst;
|
|
|
|
hr = HrGetCheckState(cfpl, dwCmdId, nccs);
|
|
if (S_OK == hr) // don't need to set if not supported on this item (S_FALSE)
|
|
{
|
|
CheckMenuItem(
|
|
hMenu,
|
|
x,
|
|
nccs == NCCS_CHECKED ?
|
|
MF_CHECKED | MF_BYPOSITION : // checked
|
|
MF_UNCHECKED | MF_BYPOSITION); // unchecked
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrBuildMenu
|
|
//
|
|
// Purpose: Build the context menu for for a given Connection Folder Entry..
|
|
//
|
|
// Arguments:
|
|
// [in out] hMenu Handle to menu which is to be updated
|
|
// [in] fVerbsOnly Should return Verbs only (shortcuts)
|
|
// [in] cfpl List (0 or more) of PIDLs that are selected
|
|
// [in] idCmdFirst Min value the handler can specify for a menu item
|
|
//
|
|
// Returns:
|
|
// none
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrBuildMenu(IN OUT HMENU &hMenu, IN BOOL fVerbsOnly, IN PCONFOLDPIDLVEC& cfpl, IN DWORD idCmdFirst)
|
|
{
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
Assert(hMenu)
|
|
if (!hMenu)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
DWORD dwCurrentDefaultPriority = 0;
|
|
|
|
BOOL fShouldAppendSeparator = FALSE;
|
|
DWORD dwInsertPos = 1;
|
|
for (DWORD x = 0; x < g_cteCommandMatrixCount && SUCCEEDED(hr); x++)
|
|
{
|
|
const COMMANDENTRY& cte = g_cteCommandMatrix[x];
|
|
|
|
if ( (fVerbsOnly) && !(cte.dwFlags & NB_VERB) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (CMIDM_SEPARATOR == cte.iCommandId)
|
|
{
|
|
fShouldAppendSeparator = TRUE;
|
|
}
|
|
else
|
|
{
|
|
NCCS_STATE nccs;
|
|
DWORD dwCustomResourceId = 0;
|
|
|
|
hr = HrGetCommandState(cfpl, cte.iCommandId, nccs, &dwCustomResourceId, x);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ( nccs != NCCS_NOTSHOWN )
|
|
{
|
|
if (fShouldAppendSeparator)
|
|
{
|
|
fShouldAppendSeparator = FALSE;
|
|
if (!InsertMenu(hMenu, dwInsertPos++, MF_BYPOSITION | MF_SEPARATOR, CMIDM_SEPARATOR, NULL))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
LPCWSTR szMenuString;
|
|
if (!dwCustomResourceId)
|
|
{
|
|
szMenuString = SzLoadIds(IDS_MENU_CMIDM_START + cte.iCommandId - CMIDM_FIRST);
|
|
}
|
|
else
|
|
{
|
|
szMenuString = SzLoadIds(dwCustomResourceId);
|
|
}
|
|
|
|
if (!InsertMenu(hMenu, dwInsertPos++, MF_BYPOSITION | MF_STRING | (nccs == NCCS_DISABLED ? MF_GRAYED : MF_ENABLED), idCmdFirst + cte.iCommandId - CMIDM_FIRST, szMenuString))
|
|
{
|
|
AssertSz(FALSE, "Couldn't append menu item");
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
else
|
|
{
|
|
if ( (nccs == NCCS_ENABLED) &&
|
|
(cte.dwDefaultPriority > dwCurrentDefaultPriority) ) // Not 0 is implied.
|
|
{
|
|
dwCurrentDefaultPriority = cte.dwDefaultPriority;
|
|
if (!SetMenuDefaultItem(hMenu, idCmdFirst + cte.iCommandId - CMIDM_FIRST, FALSE))
|
|
{
|
|
AssertSz(FALSE, "Couldn't set default menu item");
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (E_FILE_NOT_FOUND == hr)
|
|
{
|
|
AssertSz(FALSE, "Didn't find the CMDID inside CMDTABLE");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrUpdateMenuItemChecks(cfpl, hMenu, idCmdFirst);
|
|
if (S_FALSE == hr)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrUpdateMenu
|
|
//
|
|
// Purpose: Update a menu for for a given Connection Folder Entry..
|
|
//
|
|
// Arguments:
|
|
// [in out] hMenu Handle to menu which is to be updated
|
|
// [in] cfpl List (0 or more) of PIDLs that are selected
|
|
// [in] idCmdFirst Min value the handler can specify for a menu item
|
|
//
|
|
// Returns:
|
|
// none
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrUpdateMenu(IN OUT HMENU &hMenu, IN PCONFOLDPIDLVEC& cfpl, IN DWORD idCmdFirst)
|
|
{
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
Assert(hMenu)
|
|
if (!hMenu)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
int cMenuItems = GetMenuItemCount(hMenu);
|
|
|
|
for (int x = 0; x < cMenuItems; x++)
|
|
{
|
|
UINT nMenuID = GetMenuItemID(hMenu, x);
|
|
// UINT uiState = GetMenuState(hMenu, nMenuID, MF_BYCOMMAND );
|
|
|
|
NCCS_STATE nccs;
|
|
DWORD dwCustomResourceId = 0;
|
|
DWORD dwCmdId = NCCMDFromSFV(nMenuID, idCmdFirst) - idCmdFirst;
|
|
|
|
hr = HrGetCommandState(cfpl, dwCmdId, nccs, &dwCustomResourceId, 0xffffffff, NB_FLAG_ON_TOPMENU);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (nccs == NCCS_NOTSHOWN)
|
|
{
|
|
#ifdef DBG
|
|
WCHAR szTemp[MAX_PATH];
|
|
GetMenuStringW(hMenu, x, szTemp, MAX_PATH, MF_BYPOSITION );
|
|
TraceTag(ttidMenus, "Received request to permanently remove menu item: '%S' for CMDID: %d MenuID: %d", szTemp, dwCmdId, nMenuID);
|
|
#endif
|
|
RemoveMenu(hMenu, x, MF_BYPOSITION);
|
|
}
|
|
else
|
|
{
|
|
EnableMenuItem(
|
|
hMenu,
|
|
x,
|
|
nccs == NCCS_ENABLED ?
|
|
MF_ENABLED | MF_BYPOSITION: // enable
|
|
MF_GRAYED | MF_BYPOSITION);
|
|
}
|
|
}
|
|
|
|
NCCS_CHECKED_STATE nccCheckedState;
|
|
hr = HrGetCheckState(cfpl, dwCmdId, nccCheckedState);
|
|
if (S_OK == hr) // don't need to set if not supported on this item (S_FALSE)
|
|
{
|
|
CheckMenuItem(
|
|
hMenu,
|
|
x,
|
|
nccCheckedState == NCCS_CHECKED ?
|
|
MF_CHECKED | MF_BYPOSITION : // checked
|
|
MF_UNCHECKED | MF_BYPOSITION); // unchecked
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HasPermissionToRenameConnection
|
|
//
|
|
// Purpose: Checks if the Thread Local user has access to rename a given
|
|
// connection
|
|
//
|
|
// Arguments:
|
|
// [in] pcfp PIDL that wants to be renamed
|
|
//
|
|
// Returns:
|
|
// TRUE if has permissions
|
|
// FALSE if no permissions
|
|
//
|
|
// Author: deonb 8 Feb 2001
|
|
//
|
|
// Notes:
|
|
// ISSUE: Move out of this file
|
|
//
|
|
BOOL HasPermissionToRenameConnection(const PCONFOLDPIDL& pcfp)
|
|
{
|
|
TraceFileFunc(ttidMenus);
|
|
|
|
BOOL fPermission = FALSE;
|
|
|
|
// ISSUE: Due to a clarification in the spec this code is unreasonably complex.
|
|
// If possible clean it up in the future.
|
|
|
|
if (((!(pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
|
|
FHasPermissionFromCache(NCPERM_RenameMyRasConnection))))
|
|
{
|
|
fPermission = TRUE;
|
|
}
|
|
else if (FIsPolicyConfigured(NCPERM_RenameConnection))
|
|
{
|
|
if (((!(pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
|
|
FHasPermissionFromCache(NCPERM_RenameMyRasConnection))))
|
|
{
|
|
fPermission = TRUE;
|
|
}
|
|
else if ((pcfp->ncm != NCM_LAN) && (pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
|
|
FHasPermissionFromCache(NCPERM_RenameConnection) ||
|
|
(pcfp->ncm == NCM_LAN) && FHasPermissionFromCache(NCPERM_RenameConnection))
|
|
{
|
|
fPermission = TRUE;
|
|
}
|
|
}
|
|
else if (((pcfp->ncm == NCM_LAN) && FHasPermissionFromCache(NCPERM_RenameLanConnection))
|
|
|| ((pcfp->ncm != NCM_LAN) && (pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
|
|
FHasPermissionFromCache(NCPERM_RenameAllUserRasConnection)))
|
|
{
|
|
fPermission = TRUE;
|
|
}
|
|
|
|
return fPermission;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: SetConnectMenuItem
|
|
//
|
|
// Purpose: This function goes in and modifies the first menu item so
|
|
// that it shows the correct test based on the connection
|
|
// state (enabled or not) or the connection type (LAN / WAN).
|
|
//
|
|
// Arguments:
|
|
// hmenu [in] Menu to operate on
|
|
// bLan [in] Whether or not this is a LAN connection
|
|
// idCmdFirst [in] Are commands are really an offset to this value
|
|
// bEnable [in] If the connection is enabled or not
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: mbend 8 Mar 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID SetConnectMenuItem(
|
|
HMENU hmenu,
|
|
BOOL bLan,
|
|
INT idCmdFirst,
|
|
BOOL bEnable)
|
|
{
|
|
// Different strings for WAN/LAN
|
|
INT iEnableString =
|
|
bLan ? IDS_DISABLE_MENUITEM : IDS_DISCONNECT_MENUITEM;
|
|
INT iDisableString =
|
|
bLan ? IDS_ENABLE_MENUITEM : IDS_CONNECT_MENUITEM;
|
|
INT iMenuString =
|
|
bEnable ? iEnableString : iDisableString;
|
|
PCWSTR pszMenuString = SzLoadIds(iMenuString);
|
|
MENUITEMINFO mii;
|
|
// Different commands for WAN/LAN
|
|
INT iConnect = bLan ? CMIDM_ENABLE : CMIDM_CONNECT;
|
|
INT iDisconnect = bLan ? CMIDM_DISABLE : CMIDM_DISCONNECT;
|
|
INT iOffset = bEnable ? iDisconnect : iConnect;
|
|
INT iNewCommand = idCmdFirst + iOffset;
|
|
|
|
Assert(pszMenuString);
|
|
|
|
// Set the menuitem fields
|
|
//
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_TYPE | MIIM_ID;
|
|
mii.fType = MFT_STRING;
|
|
mii.dwTypeData = (PWSTR) pszMenuString;
|
|
mii.wID = iNewCommand;
|
|
|
|
// This is assuming that we want to take out the first menu item.
|
|
if (!SetMenuItemInfo(hmenu, 0, TRUE, &mii))
|
|
{
|
|
TraceTag(ttidMenus, "SetMenuItemInfo returned: 0x%08x for CMIDM_DISCONNECT",
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrSetConnectDisconnectMenuItem
|
|
//
|
|
// Purpose: Modify the menu item (if necessary) for connect/disconnect.
|
|
// We change this back and forth as needed since only one can be
|
|
// supported at a time, and those in charge don't want both
|
|
// appearing at any given time.
|
|
//
|
|
// Arguments:
|
|
// apidlSelected [in] List of selected objects
|
|
// cPidl [in] Count of selected objects
|
|
// hmenu [in] Our menu handle
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: jeffspr 1 May 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrSetConnectDisconnectMenuItem(
|
|
const PCONFOLDPIDLVEC& apidlSelected,
|
|
HMENU hmenu,
|
|
INT idCmdFirst)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (apidlSelected.size() == 1)
|
|
{
|
|
Assert(!apidlSelected[0].empty() );
|
|
|
|
const PCONFOLDPIDL& pcfp = apidlSelected[0];
|
|
|
|
switch(pcfp->ncs)
|
|
{
|
|
case NCS_CONNECTED:
|
|
case NCS_DISCONNECTING:
|
|
case NCS_MEDIA_DISCONNECTED:
|
|
case NCS_INVALID_ADDRESS:
|
|
case NCS_AUTHENTICATING:
|
|
case NCS_AUTHENTICATION_FAILED:
|
|
case NCS_AUTHENTICATION_SUCCEEDED:
|
|
case NCS_CREDENTIALS_REQUIRED:
|
|
SetConnectMenuItem(hmenu, IsMediaLocalType(pcfp->ncm), idCmdFirst, TRUE);
|
|
break;
|
|
|
|
case NCS_DISCONNECTED:
|
|
case NCS_CONNECTING:
|
|
case NCS_HARDWARE_NOT_PRESENT:
|
|
case NCS_HARDWARE_DISABLED:
|
|
case NCS_HARDWARE_MALFUNCTION:
|
|
SetConnectMenuItem(hmenu, IsMediaLocalType(pcfp->ncm), idCmdFirst, FALSE);
|
|
break;
|
|
|
|
default:
|
|
AssertSz(FALSE, "HrSetConnectDisconnectMenuItem: What in the heck state is this?");
|
|
break;
|
|
}
|
|
}
|
|
|
|
TraceHr(ttidMenus, FAL, hr, FALSE, "HrSetConnectDisconnectMenuItem");
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT HrCanRenameConnection(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
if (cfe.empty())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if (cfe.GetCharacteristics() & NCCF_INCOMING_ONLY)
|
|
{
|
|
if (cfe.GetNetConMediaType() == NCM_NONE) // Incoming server - don't care
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CPConFoldPidl<ConFoldPidl_v2> pcfp;
|
|
|
|
cfe.ConvertToPidl(pcfp);
|
|
|
|
if (!HasPermissionToRenameConnection(pcfp))
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
}
|
|
else
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
HRESULT HrCanShowProperties(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
if (cfe.empty())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if (cfe.GetCharacteristics() & NCCF_INCOMING_ONLY)
|
|
{
|
|
if (cfe.GetNetConMediaType() == NCM_NONE) // Incoming server - don't care
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
|
|
BOOL IsBridgeInstalled()
|
|
{
|
|
BOOL fBridgePresent = FALSE; // fail to false
|
|
HRESULT hResult;
|
|
|
|
IHNetCfgMgr* pHomeNetConfigManager;
|
|
hResult = HrCreateInstance(CLSID_HNetCfgMgr, CLSCTX_INPROC, &pHomeNetConfigManager);
|
|
if(SUCCEEDED(hResult))
|
|
{
|
|
IHNetBridgeSettings* pNetBridgeSettings;
|
|
hResult = pHomeNetConfigManager->QueryInterface(IID_IHNetBridgeSettings, reinterpret_cast<void**>(&pNetBridgeSettings));
|
|
if(SUCCEEDED(hResult))
|
|
{
|
|
IHNetBridge* pNetBridge;
|
|
IEnumHNetBridges* pNetBridgeEnum;
|
|
hResult = pNetBridgeSettings->EnumBridges(&pNetBridgeEnum);
|
|
if(SUCCEEDED(hResult))
|
|
{
|
|
hResult = pNetBridgeEnum->Next(1, &pNetBridge, NULL);
|
|
if(S_OK == hResult)
|
|
{
|
|
fBridgePresent = TRUE;
|
|
ReleaseObj(pNetBridge);
|
|
}
|
|
ReleaseObj(pNetBridgeEnum);
|
|
}
|
|
ReleaseObj(pNetBridgeSettings);
|
|
}
|
|
ReleaseObj(pHomeNetConfigManager);
|
|
}
|
|
return fBridgePresent;
|
|
}
|
|
|
|
HRESULT HrIsBridgeSupported(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
// if (cfe.empty())
|
|
// {
|
|
// return S_FALSE;
|
|
// }
|
|
//
|
|
#ifdef _WIN64
|
|
// Homenet technologies are not available at all on IA64
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
#else
|
|
// If the machine is Advanced server or data center, delete the bridge menu item
|
|
OSVERSIONINFOEXW verInfo = {0};
|
|
ULONGLONG ConditionMask = 0;
|
|
|
|
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
|
|
verInfo.wSuiteMask = VER_SUITE_ENTERPRISE;
|
|
|
|
VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
|
|
|
|
if (VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask))
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
BOOL fUserIsAdmin = FALSE;
|
|
HRESULT hr = S_OK;
|
|
CComPtr<INetConnectionUiUtilities> pConnectionUi;
|
|
|
|
hr = CoCreateInstance(CLSID_NetConnectionUiUtilities, NULL, CLSCTX_INPROC,
|
|
IID_INetConnectionUiUtilities, reinterpret_cast<void**>(&pConnectionUi));
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
fUserIsAdmin = FIsUserAdmin();
|
|
|
|
if (IsBridgeInstalled())
|
|
{
|
|
if (CMIDM_CREATE_BRIDGE == iCommandId)
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
else if (CMIDM_CONMENU_CREATE_BRIDGE == iCommandId)
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
return S_OK;
|
|
}
|
|
else // CMIDM_ADD_TO_BRIDGE or CMID_REMOVE_FROM_BRIDGE
|
|
{
|
|
if (!fUserIsAdmin || !pConnectionUi->UserHasPermission(NCPERM_AllowNetBridge_NLA))
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return S_FALSE; // Leave alone
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( (CMIDM_CREATE_BRIDGE == iCommandId) ||
|
|
(CMIDM_CONMENU_CREATE_BRIDGE == iCommandId) )
|
|
{
|
|
if (!fUserIsAdmin || !pConnectionUi->UserHasPermission(NCPERM_AllowNetBridge_NLA))
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return S_FALSE; // Leave alone
|
|
}
|
|
}
|
|
else // CMIDM_ADD_TO_BRIDGE or CMID_REMOVE_FROM_BRIDGE
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
HRESULT HrOsIsLikePersonal()
|
|
{
|
|
if (IsOS(OS_PERSONAL))
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
if (IsOS(OS_PROFESSIONAL))
|
|
{
|
|
LPWSTR pszDomain;
|
|
NETSETUP_JOIN_STATUS njs = NetSetupUnknownStatus;
|
|
if (NERR_Success == NetGetJoinInformation(NULL, &pszDomain, &njs))
|
|
{
|
|
NetApiBufferFree(pszDomain);
|
|
}
|
|
|
|
if (NetSetupDomainName == njs)
|
|
{
|
|
return S_FALSE; // connected to domain
|
|
}
|
|
else
|
|
{
|
|
return S_OK; // Professional, but not a domain member
|
|
}
|
|
}
|
|
return S_FALSE; // not personal or non-domain professional
|
|
}
|
|
|
|
HRESULT HrShouldHaveHomeNetWizard()
|
|
{
|
|
#ifdef _WIN64
|
|
return S_FALSE;
|
|
#else
|
|
if ( ( HrOsIsLikePersonal() == S_OK ) &&
|
|
FIsUserAdmin())
|
|
{
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
HRESULT HrIsHomeNewWizardSupported(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
if (S_OK == HrShouldHaveHomeNetWizard() )
|
|
{
|
|
nccs = NCCS_ENABLED;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
HRESULT HrIsTroubleShootSupported(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
if ( cfe.empty() && (!fMultiSelect) )
|
|
{
|
|
if ( ! IsOS(OS_ANYSERVER) )
|
|
{
|
|
nccs = NCCS_ENABLED;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
nccs = NCCS_ENABLED;
|
|
return S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nccs = NCCS_DISABLED;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
HRESULT HrIsNCWSupported(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
if ( (HrOsIsLikePersonal() == S_OK) &&
|
|
!FIsUserAdmin() )
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT HrIsMediaWireless(
|
|
IN const CConFoldEntry& cfe,
|
|
IN BOOL fMultiSelect,
|
|
IN int iCommandId,
|
|
OUT NCCS_STATE& nccs
|
|
)
|
|
{
|
|
if (cfe.GetNetConSubMediaType() != NCSM_WIRELESS)
|
|
{
|
|
nccs = NCCS_NOTSHOWN;
|
|
return S_OK;
|
|
}
|
|
|
|
return S_FALSE; // Continue with processing
|
|
} |