Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1752 lines
66 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: C M D T A B L E . C P P
  7. //
  8. // Contents: Command-table code -- determines which menu options are
  9. // available by the selection count, among other criteria
  10. //
  11. // Notes:
  12. //
  13. // Author: jeffspr 28 Jan 1998
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "foldinc.h" // Standard shell\folder includes
  19. #include "foldres.h" // Folder resource IDs
  20. #include "nsres.h" // Netshell strings
  21. #include "cmdtable.h" // Header for this file
  22. #include "ncperms.h" // For checking User's rights on actions/menu items
  23. #include "cfutils.h"
  24. #include "hnetcfg.h"
  25. #include "lm.h"
  26. //---[ Constants ]------------------------------------------------------------
  27. const DWORD NCCF_ALL = 0xffffffff; // NCCF_ALL - For all Characteristics
  28. const DWORD S_REMOVE = 2;
  29. #define TRACESTRLEN 65535
  30. // Active must be a subset of Visible (Opening connections folder using a CHK DLL asserts integrity of table).
  31. // DO NOT use NCM_ and NCS_ flags in this table!!! You should use NBM_ and NBS_ flags over here.
  32. COMMANDENTRY g_cteCommandMatrix[] =
  33. {
  34. //iCommandId dwDefaultPriority dwFlags HrEnableDisableCB HrCustomMenuStringCB
  35. // | | dwValidWhen | | |
  36. // | | | | dwMediaTypeVisible | | dwMediaTypeActive
  37. // | | | | dwStatusVisible | | dwStatusActive
  38. // | | | | dwCharacteristicsVisible | | dwCharacteristicsActive
  39. // | | | | (VISIBLE) | | (ACTIVE... (NOT REMOVED))
  40. // v v v v | v v |
  41. // v v
  42. { CMIDM_HOMENET_WIZARD, 5, NCWHEN_ANYSELECT, NB_REMOVE_TOPLEVEL_ITEM,HrIsHomeNewWizardSupported, NULL,
  43. NBM_HNW_WIZARD, NBM_HNW_WIZARD, // Media Type
  44. NBS_ANY, NBS_ANY, // Status
  45. NCCF_ALL, NCCF_ALL}, // Characteristics
  46. { CMIDM_NET_TROUBLESHOOT, 5, NCWHEN_TOPLEVEL, NB_REMOVE_TOPLEVEL_ITEM,HrIsTroubleShootSupported, NULL,
  47. NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
  48. NBS_NONE, NBS_NONE, // Status
  49. NCCF_ALL, NCCF_ALL}, // Characteristics
  50. { CMIDM_CONMENU_ADVANCED_CONFIG,
  51. 5, NCWHEN_TOPLEVEL, NB_NO_FLAGS, NULL, NULL,
  52. NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
  53. NBS_NONE, NBS_NONE, // Status
  54. NCCF_ALL, NCCF_ALL}, // Characteristics
  55. { CMIDM_CONMENU_DIALUP_PREFS,
  56. 5, NCWHEN_TOPLEVEL,
  57. NB_NO_FLAGS, NULL, NULL,
  58. NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
  59. NBS_NONE, NBS_NONE, // Status
  60. NCCF_ALL, NCCF_ALL}, // Characteristics
  61. { CMIDM_NEW_CONNECTION, 5, NCWHEN_ANYSELECT, NB_VERB, HrIsNCWSupported, NULL,
  62. NBM_MNC_WIZARD, NBM_MNC_WIZARD, // Media Type
  63. NBS_ANY, NBS_ANY, // Status
  64. NCCF_ALL, NCCF_ALL}, // Characteristics
  65. { CMIDM_CONNECT, 3, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
  66. NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, // Media Type
  67. NBS_HW_ISSUE | NBS_DISCONNECTED | NBS_CONNECTING, NBS_DISCONNECTED, // Status
  68. NCCF_ALL, NCCF_ALL}, // Characteristics
  69. { CMIDM_DISCONNECT, 0, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
  70. NBM_SHAREDACCESSHOST_RAS|NBM_ISRASTYPE,NBM_SHAREDACCESSHOST_RAS|NBM_ISRASTYPE, // Media Type
  71. NBS_IS_CONNECTED | NBS_DISCONNECTING, NBS_IS_CONNECTED, // Status
  72. NCCF_ALL, NCCF_ALL}, // Characteristics
  73. { CMIDM_ENABLE, 3, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
  74. NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE,NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE, // Media Type
  75. NBS_HW_ISSUE | NBS_DISCONNECTED | NBS_CONNECTING, NBS_DISCONNECTED, // Status
  76. NCCF_ALL, NCCF_ALL}, // Characteristics
  77. { CMIDM_DISABLE, 0, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
  78. NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE,NBM_SHAREDACCESSHOST_LAN|NBM_ISLANTYPE, // Media Type
  79. NBS_DISCONNECTING | NBS_IS_CONNECTED | NBS_MEDIA_DISCONNECTED | NBS_INVALID_ADDRESS, NBS_NOT_DISCONNECT, // Status
  80. NCCF_ALL, NCCF_ALL}, // Characteristics
  81. { CMIDM_WZCDLG_SHOW, 4, NCWHEN_ONESELECT, NB_VERB, HrIsMediaWireless, NULL,
  82. NBM_LAN, NBM_LAN, // Media Type
  83. NBS_NOT_DISCONNECT, NBS_NOT_DISCONNECT, // Status
  84. NCCF_ALL, NCCF_ALL}, // Characteristics
  85. { CMIDM_STATUS, 5, NCWHEN_ONESELECT, NB_VERB, NULL, NULL,
  86. NBM_INCOMING | NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE, NBM_INCOMING | NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE,
  87. NBS_ANY, NBS_IS_CONNECTED | NBS_INVALID_ADDRESS, // Status
  88. NCCF_ALL, NCCF_ALL}, // Characteristics
  89. { CMIDM_FIX, 0, NCWHEN_SOMESELECT, NB_NO_FLAGS, NULL, NULL,
  90. NBM_ISLANTYPE, NBM_ISLANTYPE, // Media Type
  91. NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_INVALID_ADDRESS | NBS_IS_CONNECTED, // Status
  92. NCCF_ALL, NCCF_ALL}, // Characteristics
  93. { CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
  94. { CMIDM_SET_DEFAULT, 0, NCWHEN_ONESELECT, NB_NEGATE_CHAR_MATCH, NULL, NULL,
  95. NBM_INCOMING | NBM_ISRASTYPE, NBM_INCOMING | NBM_ISRASTYPE, // Media Type
  96. NBS_ANY, NBS_ANY, // Status
  97. NCCF_INCOMING_ONLY | NCCF_DEFAULT, NCCF_INCOMING_ONLY | NCCF_DEFAULT}, // Characteristics
  98. { CMIDM_UNSET_DEFAULT, 0, NCWHEN_ONESELECT, NB_NO_FLAGS, NULL, NULL,
  99. NBM_INCOMING | NBM_ISRASTYPE, NBM_INCOMING | NBM_ISRASTYPE, // Media Type
  100. NBS_ANY, NBS_ANY, // Status
  101. NCCF_DEFAULT, NCCF_DEFAULT}, // Characteristics
  102. { CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
  103. { CMIDM_CREATE_BRIDGE, 0, NCWHEN_ANYSELECT, NB_NO_FLAGS, HrIsBridgeSupported, NULL,
  104. NBM_LAN, NBM_LAN, // Media Type
  105. NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_DISCONNECTING|NBS_IS_CONNECTED|NBS_MEDIA_DISCONNECTED|NBS_INVALID_ADDRESS, // Status
  106. NCCF_ALL, NCCF_ALL }, // Characteristics
  107. { CMIDM_CONMENU_CREATE_BRIDGE,0, NCWHEN_TOPLEVEL,NB_REMOVE_TOPLEVEL_ITEM,HrIsBridgeSupported, NULL,
  108. NBM_NOMEDIATYPE, NBM_NOMEDIATYPE, // Media Type
  109. NBS_NONE, NBS_NONE, // Status
  110. NCCF_ALL, NCCF_ALL}, // Characteristics
  111. { CMIDM_ADD_TO_BRIDGE, 0, NCWHEN_SOMESELECT, NB_NEGATE_CHAR_MATCH, HrIsBridgeSupported, NULL,
  112. NBM_LAN, NBM_LAN, // Media Type
  113. NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_DISCONNECTING|NBS_IS_CONNECTED|NBS_MEDIA_DISCONNECTED|NBS_INVALID_ADDRESS, // Status
  114. NCCF_BRIDGED | NCCF_FIREWALLED | NCCF_SHARED, NCCF_BRIDGED | NCCF_FIREWALLED | NCCF_SHARED }, // Characteristics
  115. { CMIDM_REMOVE_FROM_BRIDGE, 0, NCWHEN_SOMESELECT,NB_NO_FLAGS, HrIsBridgeSupported, NULL,
  116. NBM_LAN, NBM_LAN, // Media Type
  117. NBS_IS_CONNECTED | NBS_DISCONNECTING| NBS_MEDIA_DISCONNECTED| NBS_INVALID_ADDRESS, NBS_DISCONNECTING|NBS_IS_CONNECTED|NBS_MEDIA_DISCONNECTED|NBS_INVALID_ADDRESS, // Status
  118. NCCF_BRIDGED, NCCF_BRIDGED }, // Characteristics
  119. { CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
  120. { CMIDM_CREATE_COPY, 0, NCWHEN_ONESELECT, NB_NEGATE_VIS_CHAR_MATCH, NULL, NULL,
  121. NBM_INCOMING | NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, NBM_INCOMING | NBM_SHAREDACCESSHOST_RAS | NBM_ISRASTYPE, // Media Type
  122. NBS_ANY, NBS_ANY, // Status
  123. NCCF_INCOMING_ONLY, NCCF_ALLOW_DUPLICATION}, // Characteristics
  124. { CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
  125. { CMIDM_CREATE_SHORTCUT, 0, NCWHEN_ONESELECT, NB_NEGATE_CHAR_MATCH, NULL, NULL,
  126. NBM_ANY, NBM_ANY, // Media Type
  127. NBS_ANY, NBS_ANY, // Status
  128. NCCF_INCOMING_ONLY, NCCF_INCOMING_ONLY}, // Characteristics
  129. { CMIDM_DELETE, 0, NCWHEN_SOMESELECT, NB_NO_FLAGS, NULL, NULL,
  130. NBM_NOTWIZARD, NBM_NOTWIZARD, // Media Type
  131. NBS_ANY, NBS_ANY, // Status
  132. NCCF_ALL, NCCF_ALLOW_REMOVAL}, // Characteristics
  133. { CMIDM_RENAME, 0, NCWHEN_ONESELECT, NB_NO_FLAGS, HrCanRenameConnection, NULL,
  134. NBM_NOTWIZARD, NBM_NOTWIZARD, // Media Type
  135. NBS_ANY, NBS_ANY, // Status
  136. NCCF_ALL, NCCF_ALLOW_RENAME}, // Characteristics
  137. { CMIDM_SEPARATOR, 0,0,0,0,0, 0,0, 0,0, 0,0 },
  138. { CMIDM_PROPERTIES, 2, NCWHEN_ONESELECT, NB_NO_FLAGS, HrCanShowProperties, NULL,
  139. NBM_INCOMING|NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE, NBM_INCOMING|NBM_SHAREDACCESSHOST_LAN|NBM_SHAREDACCESSHOST_RAS|NBM_ISCONNECTIONTYPE, // Media Type
  140. NBS_ANY, NBS_ANY, // Status
  141. NCCF_ALL, NCCF_ALL}, // Characteristics
  142. };
  143. // What is the difference between NCCF_INCOMING_ONLY, ~NCCF_INCOMING_ONLY and NCCF_INCOMING_ONLY + NB_NEGATE_CHAR_MATCH?
  144. // NCCF_INCOMING_ONLY | NCCF_ALLOW_REMOVAL means: NCCF_INCOMING_ONLY or NCCF_ALLOW_REMOVAL or BOTH should be set.
  145. // ~NCCF_INCOMING_ONLY means: One or flag (irrespective of NCCF_INCOMING_ONLY flag) should be set.
  146. // NB_NEGATE_CHAR_MATCH + NCCF_INCOMING_ONLY means: Check that NCCF_INCOMING_ONLY is not set.
  147. const DWORD g_cteCommandMatrixCount = celems(g_cteCommandMatrix);
  148. COMMANDPERMISSIONSENTRY g_cteCommandPermissionsMatrix[] =
  149. {
  150. { CMIDM_NEW_CONNECTION, NBM_ANY, NCCF_ALL, NB_TOPLEVEL_PERM | NB_REMOVE_IF_NOT_MATCH,NBPERM_NewConnectionWizard, APPLY_TO_ALL_USERS },
  151. { CMIDM_CONNECT, NBM_ISRASTYPE, NCCF_ALL, NB_NO_FLAGS, NBPERM_RasConnect, APPLY_TO_ALL_USERS },
  152. { CMIDM_CONNECT, NBM_SHAREDACCESSHOST_RAS, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
  153. { CMIDM_DISCONNECT, NBM_ISRASTYPE, NCCF_INCOMING_ONLY, NB_NEGATE_CHAR_MATCH,NBPERM_RasConnect, APPLY_TO_ALL_USERS },
  154. { CMIDM_DISCONNECT, NBM_ISRASTYPE, NCCF_INCOMING_ONLY, NB_NO_FLAGS, NBPERM_RasConnect, APPLY_TO_ADMIN },
  155. { CMIDM_DISCONNECT, NBM_SHAREDACCESSHOST_RAS, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
  156. { CMIDM_ENABLE, NBM_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_LanConnect, APPLY_TO_ALL_USERS },
  157. { CMIDM_ENABLE, NBM_SHAREDACCESSHOST_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
  158. { CMIDM_ENABLE, NBM_BRIDGE, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
  159. { CMIDM_DISABLE, NBM_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_LanConnect, APPLY_TO_ALL_USERS },
  160. { CMIDM_DISABLE, NBM_SHAREDACCESSHOST_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ALL_USERS },
  161. { CMIDM_DISABLE, NBM_BRIDGE, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
  162. { CMIDM_STATUS, NBM_ANY, NCCF_INCOMING_ONLY, NB_NEGATE_CHAR_MATCH,NBPERM_Statistics, APPLY_TO_ALL_USERS },
  163. { CMIDM_STATUS, NBM_ANY, NCCF_INCOMING_ONLY, NB_NO_FLAGS, NBPERM_Statistics, APPLY_TO_ADMIN },
  164. { CMIDM_CREATE_BRIDGE, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
  165. { CMIDM_ADD_TO_BRIDGE, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
  166. { CMIDM_REMOVE_FROM_BRIDGE, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_AllowNetBridge_NLA, APPLY_TO_OPS_OR_ADMIN },
  167. { CMIDM_CREATE_COPY, NBM_ANY, NCCF_ALL_USERS, NB_NO_FLAGS, NBPERM_NewConnectionWizard | NBPERM_RasAllUserProperties, APPLY_TO_ALL_USERS },
  168. { CMIDM_CREATE_COPY, NBM_ANY, NCCF_ALL_USERS, NB_NEGATE_CHAR_MATCH,NBPERM_NewConnectionWizard, APPLY_TO_ALL_USERS },
  169. { CMIDM_FIX, NBM_ANY, NCCF_ALL, NB_NO_FLAGS, NBPERM_Repair, APPLY_TO_POWERUSERSPLUS },
  170. { CMIDM_DELETE, NBM_ANY, NCCF_ALL_USERS, NB_NO_FLAGS, NBPERM_DeleteConnection | NBPERM_DeleteAllUserConnection, APPLY_TO_ALL_USERS },
  171. { CMIDM_DELETE, NBM_ANY, NCCF_ALL_USERS, NB_NEGATE_CHAR_MATCH,NBPERM_DeleteConnection, APPLY_TO_ALL_USERS },
  172. { CMIDM_SET_DEFAULT, NBM_INCOMING |
  173. NBM_ISRASTYPE, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_OPS_OR_ADMIN },
  174. { CMIDM_UNSET_DEFAULT, NBM_INCOMING |
  175. NBM_ISRASTYPE, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_OPS_OR_ADMIN },
  176. { CMIDM_CONMENU_ADVANCED_CONFIG,
  177. NBM_ANY, NCCF_ALL_USERS, NB_TOPLEVEL_PERM, NBPERM_AdvancedSettings, APPLY_TO_ADMIN },
  178. { CMIDM_CONMENU_DIALUP_PREFS,
  179. NBM_ANY, NCCF_ALL_USERS, NB_TOPLEVEL_PERM, NBPERM_DialupPrefs, APPLY_TO_ALL_USERS },
  180. { CMIDM_PROPERTIES, NBM_INCOMING, NCCF_ALL, NB_NO_FLAGS, NBPERM_Always, APPLY_TO_ADMIN },
  181. { CMIDM_PROPERTIES, NBM_ISRASTYPE, NCCF_ALL_USERS, NB_NEGATE_CHAR_MATCH,NBPERM_RasMyProperties, APPLY_TO_ALL_USERS },
  182. { CMIDM_PROPERTIES, NBM_ISRASTYPE, NCCF_ALL_USERS, NB_NO_FLAGS, NBPERM_RasAllUserProperties, APPLY_TO_ALL_USERS },
  183. { CMIDM_PROPERTIES, NBM_LAN, NCCF_ALL, NB_NO_FLAGS, NBPERM_LanProperties, APPLY_TO_ALL_USERS }
  184. };
  185. const DWORD g_cteCommandPermissionsMatrixCount = celems(g_cteCommandPermissionsMatrix);
  186. SFVCOMMANDMAP g_cteSFVCommandMap[] =
  187. {
  188. { SFVIDM_FILE_DELETE, CMIDM_DELETE},
  189. { SFVIDM_FILE_LINK, CMIDM_CREATE_SHORTCUT},
  190. { SFVIDM_FILE_PROPERTIES, CMIDM_PROPERTIES},
  191. { SFVIDM_FILE_RENAME, CMIDM_RENAME}
  192. };
  193. const DWORD g_cteSFVCommandMapCount = celems(g_cteSFVCommandMap);
  194. CMDCHKENTRY g_cceFolderChecks[] =
  195. {
  196. // command id
  197. // currently checked
  198. // | new check state
  199. // | |
  200. // v v
  201. { CMIDM_CONMENU_OPERATOR_ASSIST, false, false }
  202. };
  203. const DWORD g_nFolderCheckCount = celems(g_cceFolderChecks);
  204. inline DWORD dwNegateIf(DWORD dwInput, DWORD dwFlags, DWORD dwNegateCondition)
  205. {
  206. if (dwFlags & dwNegateCondition)
  207. {
  208. return ~dwInput;
  209. }
  210. else
  211. {
  212. return dwInput;
  213. }
  214. }
  215. inline BOOL bContains(DWORD dwContainee, DWORD dwContainer, DWORD dwFlags, DWORD dwContaineeNegateCondition, DWORD dwContainerNegateCondition)
  216. {
  217. dwContainer = dwNegateIf(dwContainer, dwFlags, dwContainerNegateCondition);
  218. dwContainee = dwNegateIf(dwContainee, dwFlags, dwContaineeNegateCondition);
  219. if ( (dwContainee & dwContainer) != dwContainee)
  220. {
  221. return FALSE;
  222. }
  223. else
  224. {
  225. return TRUE;
  226. }
  227. }
  228. //+---------------------------------------------------------------------------
  229. //
  230. // Member: HrAssertIntegrityAgainstOldMatrix
  231. //
  232. // Purpose: Asserts the internal integrity of the Command Matrix
  233. // Currently checks for:
  234. // 1. No duplicate CMDIDs
  235. // 2. Each NCWHEN flag at least specified NCWHEN_ONESELECT
  236. //
  237. // Arguments:
  238. // none
  239. //
  240. // Returns:
  241. // S_OK is succeeded
  242. // E_FAIL if not
  243. //
  244. // Author: deonb 8 Feb 2001
  245. //
  246. // Notes: Asserts on failure
  247. //
  248. HRESULT HrAssertCommandMatrixIntegrity()
  249. {
  250. TraceFileFunc(ttidMenus);
  251. HRESULT hr = S_OK;
  252. LPSTR szErr = new CHAR[TRACESTRLEN];
  253. for (DWORD x = 0; x < g_cteCommandMatrixCount; x++)
  254. {
  255. // Check that there isn't another entry with the same CommandID and Media Type.
  256. const COMMANDENTRY& cte = g_cteCommandMatrix[x];
  257. if (CMIDM_SEPARATOR == cte.iCommandId)
  258. {
  259. continue;
  260. }
  261. for (DWORD y = x + 1; y < g_cteCommandMatrixCount; y++)
  262. {
  263. const COMMANDENTRY& ctecmp = g_cteCommandMatrix[y];
  264. if (cte.iCommandId == ctecmp.iCommandId)
  265. {
  266. sprintf(szErr, "Multiple lines (%d and %d) in the COMMANDENTRY table describe the same CmdID", x+1, y+1);
  267. AssertSz(FALSE, szErr);
  268. hr = E_FAIL;
  269. }
  270. }
  271. if ( !bContains(cte.dwCharacteristicsActive, cte.dwCharacteristicsVisible, cte.dwFlags, NB_NEGATE_ACT_CHAR_MATCH, NB_NEGATE_VIS_CHAR_MATCH) )
  272. {
  273. sprintf(szErr, "Row %d. ACTIVE flags not a subset of VISIBLE flags for Characteristics? ", x+1);
  274. AssertSz(FALSE, szErr);
  275. hr = E_FAIL;
  276. }
  277. if ( !bContains(cte.dwStatusActive, cte.dwStatusVisible, cte.dwFlags, NB_NEGATE_ACT_NBS_MATCH, NB_NEGATE_VIS_NBS_MATCH) )
  278. {
  279. sprintf(szErr, "Row %d. ACTIVE flags not a subset of VISIBLE flags for Status... did you use NCS_ instead of NBM_? ", x+1);
  280. AssertSz(FALSE, szErr);
  281. hr = E_FAIL;
  282. }
  283. if ( !bContains(cte.dwMediaTypeActive, cte.dwMediaTypeVisible, cte.dwFlags, NB_NEGATE_ACT_NBM_MATCH, NB_NEGATE_VIS_NBM_MATCH) )
  284. {
  285. sprintf(szErr, "Row %d. ACTIVE flags not a subset of VISIBLE flags for MediaType... did you use NCM_ instead of NBM_? ", x+1);
  286. AssertSz(FALSE, szErr);
  287. hr = E_FAIL;
  288. }
  289. }
  290. // Assert the permissions table
  291. for (x = 0; x < g_cteCommandPermissionsMatrixCount; x++)
  292. {
  293. const COMMANDPERMISSIONSENTRY cpe = g_cteCommandPermissionsMatrix[x];
  294. // Check that each CMD entry has a corresponding entry in the Command Table
  295. BOOL bFound = FALSE;
  296. for (DWORD y = 0; y < g_cteCommandMatrixCount; y++)
  297. {
  298. const COMMANDENTRY& ctecmp = g_cteCommandMatrix[y];
  299. if (cpe.iCommandId == ctecmp.iCommandId)
  300. {
  301. bFound = TRUE;
  302. if ( (cpe.dwMediaType != NBM_ANY) &&
  303. ((cpe.dwMediaType & ctecmp.dwMediaTypeActive) != cpe.dwMediaType) )
  304. {
  305. 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);
  306. AssertSz(FALSE, szErr);
  307. hr = E_FAIL;
  308. }
  309. // if ( (cpe.dwCharacteristicsActive != NCCF_ALL) &&
  310. // ((cpe.dwCharacteristicsActive & ctecmp.dwCharacteristicsActive) != cpe.dwCharacteristicsActive) )
  311. // {
  312. // 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);
  313. // AssertSz(FALSE, szErr);
  314. // hr = E_FAIL;
  315. // }
  316. }
  317. }
  318. if (!bFound)
  319. {
  320. sprintf(szErr, "An entry has been found in the Permissions table (row %d) without a corresponding CMDID entry in the Command Table", x+1);
  321. AssertSz(FALSE, szErr);
  322. hr = E_FAIL;
  323. }
  324. // Check that no CmdId/MediaType/Characteristics has been duplicated
  325. for (y = x + 1; y < g_cteCommandPermissionsMatrixCount; y++)
  326. {
  327. const COMMANDPERMISSIONSENTRY& cpecmp = g_cteCommandPermissionsMatrix[y];
  328. if ( (cpe.iCommandId == cpecmp.iCommandId) &&
  329. (dwNegateIf(cpe.dwMediaType, cpe.dwFlags, NB_NEGATE_NBM_MATCH) &
  330. dwNegateIf(cpecmp.dwMediaType, cpecmp.dwFlags, NB_NEGATE_NBM_MATCH)) &&
  331. (dwNegateIf(cpe.dwCharacteristicsActive, cpe.dwFlags, NB_NEGATE_CHAR_MATCH) &
  332. dwNegateIf(cpecmp.dwCharacteristicsActive, cpecmp.dwFlags, NB_NEGATE_CHAR_MATCH)) )
  333. {
  334. sprintf(szErr, "Multiple lines (%d and %d) in the COMMANDENTRY table describe the same CmdID/MediaType/Characteristics combo", x+1, y+1);
  335. AssertSz(FALSE, szErr);
  336. hr = E_FAIL;
  337. }
  338. }
  339. if (! ((APPLY_TO_NETCONFIGOPS & cpe.ncpAppliesTo) ||
  340. (APPLY_TO_USER & cpe.ncpAppliesTo) ||
  341. (APPLY_TO_ADMIN & cpe.ncpAppliesTo) ||
  342. (APPLY_TO_POWERUSERS & cpe.ncpAppliesTo) ))
  343. {
  344. sprintf(szErr, "Lines (%d) in the Permissionstable - permissions must apply to someone", x+1);
  345. AssertSz(FALSE, szErr);
  346. hr = E_FAIL;
  347. }
  348. // !!(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...
  349. // kill me... kill me now.
  350. if ((!!(cpe.dwFlags & NB_NEGATE_VIS_NBM_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_NBM_MATCH)) ||
  351. (!!(cpe.dwFlags & NB_NEGATE_VIS_NBS_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_NBS_MATCH)) ||
  352. (!!(cpe.dwFlags & NB_NEGATE_VIS_CHAR_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_CHAR_MATCH)) ||
  353. (!!(cpe.dwFlags & NB_NEGATE_VIS_PERMS_MATCH) != !!(cpe.dwFlags & NB_NEGATE_ACT_PERMS_MATCH)) )
  354. {
  355. 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);
  356. AssertSz(FALSE, szErr);
  357. hr = E_FAIL;
  358. }
  359. }
  360. delete[] szErr;
  361. return hr;
  362. }
  363. //+---------------------------------------------------------------------------
  364. //
  365. // Member: HrAssertMenuStructuresValid
  366. //
  367. // Purpose: Runs various asserts to make sure the menu structures are intact
  368. // Called on NetShell startup
  369. //
  370. // Arguments:
  371. // [in] hwndOwner Owner window
  372. //
  373. // Returns:
  374. // S_OK is succeeded
  375. // E_FAIL if not
  376. //
  377. // Author: deonb 8 Feb 2001
  378. //
  379. // Notes: Asserts on failure
  380. //
  381. HRESULT HrAssertMenuStructuresValid(HWND hwndOwner)
  382. {
  383. #ifdef DBG
  384. static fBeenHereDoneThat = FALSE;
  385. if (fBeenHereDoneThat)
  386. {
  387. return S_OK;
  388. }
  389. else
  390. {
  391. fBeenHereDoneThat = TRUE;
  392. }
  393. TraceFileFunc(ttidMenus);
  394. HRESULT hr;
  395. hr = HrAssertCommandMatrixIntegrity();
  396. return hr;
  397. #else
  398. return S_OK;
  399. #endif
  400. }
  401. //+---------------------------------------------------------------------------
  402. //
  403. // Member: AdjustNCCS
  404. //
  405. // Purpose: Up-adjusts an NCCS_STATE flag. Will move ENABLED to DISABLED,
  406. // and DISABLED to REMOVE but not backwards.
  407. //
  408. // Arguments:
  409. // [in out] nccsCurrent NCCS to be adjusted
  410. // [in] nccsNew New state
  411. //
  412. // Returns:
  413. // none
  414. //
  415. // Author: deonb 8 Feb 2001
  416. //
  417. // Notes:
  418. //
  419. inline void AdjustNCCS(OUT IN NCCS_STATE& nccsCurrent, IN NCCS_STATE nccsNew)
  420. {
  421. if (nccsNew > nccsCurrent)
  422. {
  423. nccsCurrent = nccsNew;
  424. }
  425. }
  426. inline BOOL fMatchFlags(IN DWORD dwFlagsMask, IN DWORD dwFlagsTest, IN DWORD dwNegateFlagMask, IN DWORD dwNegateFlagTest)
  427. {
  428. bool bMatch = FALSE;
  429. if ( (0xffffffff == dwFlagsTest) || // Means always succeed.
  430. (dwFlagsMask & dwFlagsTest) )
  431. {
  432. bMatch = TRUE;
  433. }
  434. else
  435. {
  436. bMatch = FALSE;
  437. }
  438. if ( (dwNegateFlagMask & dwNegateFlagTest) == dwNegateFlagTest) // Do a negative compare
  439. {
  440. return !bMatch;
  441. }
  442. else
  443. {
  444. return bMatch;
  445. }
  446. }
  447. //+---------------------------------------------------------------------------
  448. //
  449. // Member: HrGetCommandStateFromCMDTABLEEntry
  450. //
  451. // Purpose: Get the command state for a given Connection Folder Entry,
  452. // given the Command Table Entry entry that should be used.
  453. //
  454. // Arguments:
  455. // [in] cfe Connection Folder Entry
  456. // [in] cte Command Table Entry
  457. // [in] fMultiSelect Was this part of a multi-selection?
  458. // [out] nccs State that the item should be (NCCS_ENABLED/NCCS_DISABLED/NCCS_NOTSHOWN)
  459. //
  460. // Returns:
  461. // none
  462. //
  463. // Author: deonb 8 Feb 2001
  464. //
  465. // Notes: This function uses Cached Permissions. YOU MUST CALL RefreshAllPermission before calling this function.
  466. //
  467. HRESULT HrGetCommandStateFromCMDTABLEEntry(IN const CConFoldEntry& cfe, IN const COMMANDENTRY& cte, IN BOOL fMultiSelect, OUT NCCS_STATE& nccs, OUT LPDWORD pdwResourceId)
  468. {
  469. TraceFileFunc(ttidMenus);
  470. Assert(pdwResourceId);
  471. HRESULT hr = S_OK;
  472. nccs = NCCS_ENABLED;
  473. DWORD dwNCMbm = (1 << cfe.GetNetConMediaType()); // Convert to bitmask
  474. // If we're a wizard, add as Wizard media type.
  475. if (cfe.GetWizard() == WIZARD_MNC)
  476. {
  477. dwNCMbm |= NBM_MNC_WIZARD;
  478. dwNCMbm &= ~NBM_INCOMING; // clear the INCOMINGCONNECTIONS flag (old NCM_NONE) if we're a wizard.
  479. }
  480. else if (cfe.GetWizard() == WIZARD_HNW)
  481. {
  482. dwNCMbm |= NBM_HNW_WIZARD;
  483. dwNCMbm &= ~NBM_INCOMING; // clear the INCOMINGCONNECTIONS flag (old NCM_NONE) if we're a wizard.
  484. }
  485. DWORD dwNCSbm = (1 << cfe.GetNetConStatus()); // Convert to bitmask
  486. DWORD dwNCCF = cfe.GetCharacteristics(); // Already a bitmask
  487. // Check if the command can participate in multi-select
  488. if ( fMultiSelect &&
  489. !(cte.dwValidWhen & NCWHEN_MULTISELECT) )
  490. {
  491. AdjustNCCS(nccs, NCCS_DISABLED);
  492. }
  493. // Check if the command should be visible
  494. if (!((fMatchFlags(dwNCMbm, cte.dwMediaTypeVisible, cte.dwFlags, NB_NEGATE_VIS_NBM_MATCH)) &&
  495. (fMatchFlags(dwNCSbm, cte.dwStatusVisible, cte.dwFlags, NB_NEGATE_VIS_NBS_MATCH)) &&
  496. (fMatchFlags(dwNCCF , cte.dwCharacteristicsVisible,cte.dwFlags, NB_NEGATE_VIS_CHAR_MATCH)) ))
  497. {
  498. AdjustNCCS(nccs, NCCS_NOTSHOWN);
  499. }
  500. // Check if the command should be grayed out
  501. if (!((fMatchFlags(dwNCMbm, cte.dwMediaTypeActive, cte.dwFlags, NB_NEGATE_ACT_NBM_MATCH)) &&
  502. (fMatchFlags(dwNCSbm, cte.dwStatusActive, cte.dwFlags, NB_NEGATE_ACT_NBS_MATCH)) &&
  503. (fMatchFlags(dwNCCF , cte.dwCharacteristicsActive, cte.dwFlags, NB_NEGATE_ACT_CHAR_MATCH)) ))
  504. {
  505. AdjustNCCS(nccs, NCCS_DISABLED);
  506. }
  507. // Check if the command should be grayed out based on permissions
  508. for (DWORD x = 0; nccs == NCCS_ENABLED, x < g_cteCommandPermissionsMatrixCount; x++)// Permissions won't affect NOT_SHOWN or DISABLED
  509. {
  510. const COMMANDPERMISSIONSENTRY cpe = g_cteCommandPermissionsMatrix[x];
  511. if ( (cpe.iCommandId == cte.iCommandId) &&
  512. (fMatchFlags(dwNCMbm, cpe.dwMediaType, cpe.dwFlags, NB_NEGATE_NBM_MATCH)) &&
  513. (fMatchFlags(dwNCCF, cpe.dwCharacteristicsActive, cpe.dwFlags, NB_NEGATE_CHAR_MATCH)) )
  514. {
  515. for (DWORD dwPerm = 0; dwPerm < sizeof(DWORD)*8; dwPerm++)
  516. {
  517. if (cpe.dwPermissionsActive & (1 << static_cast<DWORD64>(dwPerm)) )
  518. {
  519. if (!FHasPermissionFromCache(dwPerm))
  520. {
  521. if (cpe.dwFlags & NB_REMOVE_IF_NOT_MATCH)
  522. {
  523. AdjustNCCS(nccs, NCCS_NOTSHOWN);
  524. }
  525. else
  526. {
  527. AdjustNCCS(nccs, NCCS_DISABLED);
  528. }
  529. break; // will break anyway.
  530. }
  531. }
  532. }
  533. if (APPLY_TO_USER & cpe.ncpAppliesTo)
  534. {
  535. break;
  536. }
  537. if ( (APPLY_TO_POWERUSERS & cpe.ncpAppliesTo) && FIsUserPowerUser() )
  538. {
  539. break;
  540. }
  541. if ( (APPLY_TO_NETCONFIGOPS & cpe.ncpAppliesTo) && FIsUserNetworkConfigOps() )
  542. {
  543. break;
  544. }
  545. if ( (APPLY_TO_ADMIN & cpe.ncpAppliesTo) && FIsUserAdmin())
  546. {
  547. break;
  548. }
  549. // At this point all group access checks failed, so disable the connection.
  550. AdjustNCCS(nccs, NCCS_DISABLED);
  551. break;
  552. }
  553. }
  554. // Check for callback
  555. if ( (nccs != NCCS_NOTSHOWN) &&
  556. (cte.pfnHrEnableDisableCB) )
  557. {
  558. HRESULT hrTmp;
  559. NCCS_STATE nccsTemp;
  560. hrTmp = (*cte.pfnHrEnableDisableCB)(cfe, fMultiSelect, cte.iCommandId, nccsTemp);
  561. if (S_OK == hrTmp)
  562. {
  563. AdjustNCCS(nccs, nccsTemp);
  564. }
  565. else
  566. {
  567. if (FAILED(hrTmp))
  568. {
  569. AdjustNCCS(nccs, NCCS_NOTSHOWN);
  570. }
  571. } // If the function returns S_FALSE it's an indication it didn't change the state.
  572. }
  573. // Check for Resource String callback:
  574. if ( (nccs != NCCS_NOTSHOWN) && // What's the point?
  575. (0 == *pdwResourceId) && // Must not already have a resource Id
  576. (cte.pfnHrCustomMenuStringCB) )
  577. {
  578. HRESULT hrTmp;
  579. DWORD dwResourceIdTmp = *pdwResourceId;
  580. hrTmp = (*cte.pfnHrCustomMenuStringCB)(cfe, cte.iCommandId, &dwResourceIdTmp);
  581. if (S_OK == hr)
  582. {
  583. *pdwResourceId = dwResourceIdTmp;
  584. }
  585. }
  586. return hr;
  587. }
  588. //+---------------------------------------------------------------------------
  589. //
  590. // Member: HrGetCommandState
  591. //
  592. // Purpose: Get the command state for a given Connection Folder Entry,
  593. // given the Command ID.
  594. //
  595. // Arguments:
  596. // [in] cfpl List (0 or more) of PIDLs that are selected
  597. // [in] dwCmdID Command ID
  598. // [out] nccs State that the item should be (NCCS_ENABLED/NCCS_DISABLED/NCCS_NOTSHOWN)
  599. //
  600. // Returns:
  601. // none
  602. //
  603. // Author: deonb 8 Feb 2001
  604. //
  605. // Notes:
  606. //
  607. HRESULT HrGetCommandState(IN const PCONFOLDPIDLVEC& cfpl, IN const DWORD dwCmdID, OUT NCCS_STATE& nccs, OUT LPDWORD pdwResourceId, IN DWORD cteHint, IN DWORD dwOverrideFlag)
  608. {
  609. TraceFileFunc(ttidMenus);
  610. Assert(pdwResourceId);
  611. if (!pdwResourceId)
  612. {
  613. return E_POINTER;
  614. }
  615. RefreshAllPermission();
  616. HRESULT hr = S_OK;
  617. BOOL bFound = FALSE;
  618. DWORD dwNumItems = cfpl.size();
  619. *pdwResourceId = 0;
  620. if ( dwOverrideFlag & NB_FLAG_ON_TOPMENU )
  621. {
  622. for (DWORD x = 0; x < g_cteCommandMatrixCount; x++)
  623. {
  624. if ( (g_cteCommandMatrix[x].iCommandId == dwCmdID) )
  625. {
  626. bFound = TRUE;
  627. const COMMANDENTRY& cte = g_cteCommandMatrix[x];
  628. if ((cte.dwValidWhen == NCWHEN_TOPLEVEL) || // Toplevel-ONLY menu (doesn't matter if items).
  629. ((cte.dwValidWhen & NCWHEN_TOPLEVEL) &&
  630. (!dwNumItems || (cte.dwValidWhen & NCWHEN_TOPLEVEL_DISREGARD_ITEM)) ) )
  631. { // Must be marked to allow incompatible selection,
  632. nccs = NCCS_ENABLED; // Otherwise, we'll do the item check (below).
  633. // Check for permissions
  634. for (DWORD x = 0; nccs == NCCS_ENABLED, x < g_cteCommandPermissionsMatrixCount; x++)// Permissions won't affect NOT_SHOWN or DISABLED
  635. {
  636. const COMMANDPERMISSIONSENTRY cpe = g_cteCommandPermissionsMatrix[x];
  637. if ( (cpe.iCommandId == cte.iCommandId) &&
  638. (cpe.dwFlags & NB_TOPLEVEL_PERM) )
  639. {
  640. for (DWORD dwPerm = 0; dwPerm < sizeof(DWORD)*8; dwPerm++)
  641. {
  642. if (cpe.dwPermissionsActive & (1 << static_cast<DWORD64>(dwPerm)) )
  643. {
  644. if (!FHasPermissionFromCache(dwPerm))
  645. {
  646. if (cpe.dwFlags & NB_REMOVE_IF_NOT_MATCH)
  647. {
  648. AdjustNCCS(nccs, NCCS_NOTSHOWN);
  649. }
  650. else
  651. {
  652. AdjustNCCS(nccs, NCCS_DISABLED);
  653. }
  654. break; // will break anyway.
  655. }
  656. }
  657. }
  658. if (APPLY_TO_USER & cpe.ncpAppliesTo)
  659. {
  660. break;
  661. }
  662. if ( (APPLY_TO_NETCONFIGOPS & cpe.ncpAppliesTo) && FIsUserNetworkConfigOps() )
  663. {
  664. break;
  665. }
  666. if ( (APPLY_TO_ADMIN & cpe.ncpAppliesTo) && FIsUserAdmin())
  667. {
  668. break;
  669. }
  670. // At this point all group access checks failed, so disable the connection.
  671. AdjustNCCS(nccs, NCCS_DISABLED);
  672. break;
  673. }
  674. }
  675. // Check for callback
  676. if (cte.pfnHrEnableDisableCB)
  677. {
  678. HRESULT hrTmp;
  679. NCCS_STATE nccsTemp;
  680. CONFOLDENTRY cfe;
  681. cfe.clear();
  682. if (dwNumItems > 0)
  683. {
  684. hrTmp = cfpl[0].ConvertToConFoldEntry(cfe);
  685. if (FAILED(hrTmp))
  686. {
  687. cfe.clear();
  688. }
  689. }
  690. hrTmp = (*cte.pfnHrEnableDisableCB)(cfe, dwNumItems > 1, cte.iCommandId, nccsTemp);
  691. if (S_OK == hrTmp)
  692. {
  693. AdjustNCCS(nccs, nccsTemp);
  694. }
  695. else
  696. {
  697. if (FAILED(hrTmp))
  698. {
  699. AdjustNCCS(nccs, NCCS_NOTSHOWN);
  700. }
  701. } // If the function returns S_FALSE it's an indication it didn't change the state.
  702. }
  703. if (!(NB_REMOVE_TOPLEVEL_ITEM & cte.dwFlags))
  704. {
  705. if (nccs == NCCS_NOTSHOWN)
  706. {
  707. nccs = NCCS_DISABLED;
  708. }
  709. }
  710. return S_OK;
  711. }
  712. break; // we won't find another CMDID
  713. }
  714. }
  715. if (!dwNumItems)
  716. {
  717. nccs = NCCS_DISABLED;
  718. if (bFound)
  719. {
  720. return S_OK;
  721. }
  722. else
  723. {
  724. return E_FILE_NOT_FOUND;
  725. }
  726. }
  727. }
  728. AssertSz(dwNumItems, "You don't have any items selected, but you're not a top-level menu... how come?");
  729. bFound = FALSE;
  730. nccs = NCCS_ENABLED;
  731. // This will effectively loop through all the selected PIDLs and apply the strictest
  732. // nccs that applies to everything.
  733. for (PCONFOLDPIDLVEC::const_iterator cfp = cfpl.begin(); cfp != cfpl.end(); cfp++)
  734. {
  735. CONFOLDENTRY cfe;
  736. hr = cfp->ConvertToConFoldEntry(cfe);
  737. if (FAILED(hr))
  738. {
  739. return E_FAIL;
  740. }
  741. DWORD dwPos = 0xffffffff;
  742. // This is a O(n^(2+)) algorithm when called from HrBuildMenu.
  743. // We pass a hint to check if we can quickly find the cte.
  744. if ( (cteHint != 0xffffffff) &&
  745. (g_cteCommandMatrix[cteHint].iCommandId == dwCmdID) )
  746. {
  747. dwPos = cteHint;
  748. }
  749. if (dwPos == 0xffffffff)
  750. {
  751. for (DWORD x = 0; x < g_cteCommandMatrixCount && SUCCEEDED(hr); x++)
  752. {
  753. if (g_cteCommandMatrix[x].iCommandId == dwCmdID)
  754. {
  755. dwPos = x;
  756. break;
  757. }
  758. }
  759. }
  760. if (dwPos == 0xffffffff)
  761. {
  762. return E_FILE_NOT_FOUND;
  763. }
  764. else
  765. {
  766. bFound = TRUE;
  767. NCCS_STATE nccsTmp;
  768. hr = HrGetCommandStateFromCMDTABLEEntry(cfe, g_cteCommandMatrix[dwPos], dwNumItems != 1, nccsTmp, pdwResourceId);
  769. if (FAILED(hr))
  770. {
  771. return hr;
  772. }
  773. AdjustNCCS(nccs, nccsTmp);
  774. if ( (dwOverrideFlag & NB_FLAG_ON_TOPMENU) &&
  775. (!(NB_REMOVE_TOPLEVEL_ITEM & g_cteCommandMatrix[dwPos].dwFlags)) &&
  776. (nccs == NCCS_NOTSHOWN) )
  777. {
  778. nccs = NCCS_DISABLED;
  779. }
  780. }
  781. }
  782. if (!bFound)
  783. {
  784. return E_FILE_NOT_FOUND;
  785. }
  786. return S_OK;
  787. }
  788. //+---------------------------------------------------------------------------
  789. //
  790. // Member: HrGetCheckState
  791. //
  792. // Purpose: Get the check state for a given Connection Folder Entry,
  793. // given the Command ID.
  794. //
  795. // Arguments:
  796. // [in] cfpl List (0 or more) of PIDLs that are selected
  797. // [in] dwCmdID Command ID
  798. // [out] nccs State that the item should be (NCCS_CHECKED/NCCS_UNCHECKED)
  799. //
  800. // Returns:
  801. // HRESULT
  802. //
  803. // Author: deonb 7 Mar 2001
  804. //
  805. // Notes:
  806. //
  807. HRESULT HrGetCheckState(IN const PCONFOLDPIDLVEC& cfpl, IN const DWORD dwCmdID, OUT NCCS_CHECKED_STATE& nccs)
  808. {
  809. HRESULT hr = S_FALSE;
  810. DWORD dwLoop = 0;
  811. nccs = NCCS_UNCHECKED;
  812. for (; dwLoop < g_nFolderCheckCount; dwLoop++)
  813. {
  814. if (dwCmdID == g_cceFolderChecks[dwLoop].iCommandId)
  815. {
  816. switch(g_cceFolderChecks[dwLoop].iCommandId)
  817. {
  818. case CMIDM_CONMENU_OPERATOR_ASSIST:
  819. hr = S_OK;
  820. if (g_fOperatorAssistEnabled)
  821. {
  822. nccs = NCCS_CHECKED;
  823. }
  824. break;
  825. default:
  826. break;
  827. }
  828. }
  829. }
  830. return S_OK;
  831. }
  832. //+---------------------------------------------------------------------------
  833. //
  834. // Member: NCCMDFromSFV
  835. //
  836. // Purpose: Return a NetShell CMDID for Shell Internal IDs
  837. //
  838. // Arguments:
  839. // [in] iCmdID CMDID to map
  840. //
  841. // Returns:
  842. // Returns iCmdID if not shell message, or a iCmdID mapping
  843. //
  844. // Author: deonb 8 Feb 2001
  845. //
  846. // Notes:
  847. //
  848. int NCCMDFromSFV(int iCmdID, DWORD idCmdFirst)
  849. {
  850. for (int x = 0; x < g_cteSFVCommandMapCount; x++)
  851. {
  852. if (g_cteSFVCommandMap[x].iSFVCommandId == iCmdID)
  853. {
  854. return g_cteSFVCommandMap[x].iCommandId + idCmdFirst;
  855. }
  856. }
  857. return iCmdID;
  858. }
  859. //+---------------------------------------------------------------------------
  860. //
  861. // Function: HrUpdateMenuItemChecks
  862. //
  863. // Purpose: Walk through the list of checkmark-able commands and check if
  864. // applicable.
  865. //
  866. // Arguments:
  867. // None
  868. //
  869. // Returns:
  870. //
  871. // Author: deonb 7 Mar 2001
  872. //
  873. // Notes:
  874. //
  875. HRESULT HrUpdateMenuItemChecks(IN PCONFOLDPIDLVEC& cfpl, IN OUT HMENU hMenu, IN DWORD idCmdFirst)
  876. {
  877. HRESULT hr = S_FALSE;
  878. DWORD dwLoop = 0;
  879. Assert(hMenu)
  880. if (!hMenu)
  881. {
  882. return E_INVALIDARG;
  883. }
  884. int cMenuItems = GetMenuItemCount(hMenu);
  885. for (int x = 0; x < cMenuItems; x++)
  886. {
  887. UINT nMenuID = GetMenuItemID(hMenu, x);
  888. NCCS_CHECKED_STATE nccs;
  889. DWORD dwCustomResourceId = 0;
  890. DWORD dwCmdId = NCCMDFromSFV(nMenuID, idCmdFirst) - idCmdFirst;
  891. hr = HrGetCheckState(cfpl, dwCmdId, nccs);
  892. if (S_OK == hr) // don't need to set if not supported on this item (S_FALSE)
  893. {
  894. CheckMenuItem(
  895. hMenu,
  896. x,
  897. nccs == NCCS_CHECKED ?
  898. MF_CHECKED | MF_BYPOSITION : // checked
  899. MF_UNCHECKED | MF_BYPOSITION); // unchecked
  900. }
  901. }
  902. return S_OK;
  903. }
  904. //+---------------------------------------------------------------------------
  905. //
  906. // Member: HrBuildMenu
  907. //
  908. // Purpose: Build the context menu for for a given Connection Folder Entry..
  909. //
  910. // Arguments:
  911. // [in out] hMenu Handle to menu which is to be updated
  912. // [in] fVerbsOnly Should return Verbs only (shortcuts)
  913. // [in] cfpl List (0 or more) of PIDLs that are selected
  914. // [in] idCmdFirst Min value the handler can specify for a menu item
  915. //
  916. // Returns:
  917. // none
  918. //
  919. // Author: deonb 8 Feb 2001
  920. //
  921. // Notes:
  922. //
  923. HRESULT HrBuildMenu(IN OUT HMENU &hMenu, IN BOOL fVerbsOnly, IN PCONFOLDPIDLVEC& cfpl, IN DWORD idCmdFirst)
  924. {
  925. TraceFileFunc(ttidMenus);
  926. HRESULT hr = S_OK;
  927. Assert(hMenu)
  928. if (!hMenu)
  929. {
  930. return E_INVALIDARG;
  931. }
  932. DWORD dwCurrentDefaultPriority = 0;
  933. BOOL fShouldAppendSeparator = FALSE;
  934. DWORD dwInsertPos = 1;
  935. for (DWORD x = 0; x < g_cteCommandMatrixCount && SUCCEEDED(hr); x++)
  936. {
  937. const COMMANDENTRY& cte = g_cteCommandMatrix[x];
  938. if ( (fVerbsOnly) && !(cte.dwFlags & NB_VERB) )
  939. {
  940. continue;
  941. }
  942. if (CMIDM_SEPARATOR == cte.iCommandId)
  943. {
  944. fShouldAppendSeparator = TRUE;
  945. }
  946. else
  947. {
  948. NCCS_STATE nccs;
  949. DWORD dwCustomResourceId = 0;
  950. hr = HrGetCommandState(cfpl, cte.iCommandId, nccs, &dwCustomResourceId, x);
  951. if (SUCCEEDED(hr))
  952. {
  953. if ( nccs != NCCS_NOTSHOWN )
  954. {
  955. if (fShouldAppendSeparator)
  956. {
  957. fShouldAppendSeparator = FALSE;
  958. if (!InsertMenu(hMenu, dwInsertPos++, MF_BYPOSITION | MF_SEPARATOR, CMIDM_SEPARATOR, NULL))
  959. {
  960. hr = HRESULT_FROM_WIN32(GetLastError());
  961. }
  962. }
  963. LPCWSTR szMenuString;
  964. if (!dwCustomResourceId)
  965. {
  966. szMenuString = SzLoadIds(IDS_MENU_CMIDM_START + cte.iCommandId - CMIDM_FIRST);
  967. }
  968. else
  969. {
  970. szMenuString = SzLoadIds(dwCustomResourceId);
  971. }
  972. if (!InsertMenu(hMenu, dwInsertPos++, MF_BYPOSITION | MF_STRING | (nccs == NCCS_DISABLED ? MF_GRAYED : MF_ENABLED), idCmdFirst + cte.iCommandId - CMIDM_FIRST, szMenuString))
  973. {
  974. AssertSz(FALSE, "Couldn't append menu item");
  975. hr = HRESULT_FROM_WIN32(GetLastError());
  976. }
  977. else
  978. {
  979. if ( (nccs == NCCS_ENABLED) &&
  980. (cte.dwDefaultPriority > dwCurrentDefaultPriority) ) // Not 0 is implied.
  981. {
  982. dwCurrentDefaultPriority = cte.dwDefaultPriority;
  983. if (!SetMenuDefaultItem(hMenu, idCmdFirst + cte.iCommandId - CMIDM_FIRST, FALSE))
  984. {
  985. AssertSz(FALSE, "Couldn't set default menu item");
  986. hr = HRESULT_FROM_WIN32(GetLastError());
  987. }
  988. }
  989. }
  990. }
  991. }
  992. else
  993. {
  994. if (E_FILE_NOT_FOUND == hr)
  995. {
  996. AssertSz(FALSE, "Didn't find the CMDID inside CMDTABLE");
  997. }
  998. }
  999. }
  1000. }
  1001. if (SUCCEEDED(hr))
  1002. {
  1003. hr = HrUpdateMenuItemChecks(cfpl, hMenu, idCmdFirst);
  1004. if (S_FALSE == hr)
  1005. {
  1006. hr = S_OK;
  1007. }
  1008. }
  1009. return hr;
  1010. }
  1011. //+---------------------------------------------------------------------------
  1012. //
  1013. // Member: HrUpdateMenu
  1014. //
  1015. // Purpose: Update a menu for for a given Connection Folder Entry..
  1016. //
  1017. // Arguments:
  1018. // [in out] hMenu Handle to menu which is to be updated
  1019. // [in] cfpl List (0 or more) of PIDLs that are selected
  1020. // [in] idCmdFirst Min value the handler can specify for a menu item
  1021. //
  1022. // Returns:
  1023. // none
  1024. //
  1025. // Author: deonb 8 Feb 2001
  1026. //
  1027. // Notes:
  1028. //
  1029. HRESULT HrUpdateMenu(IN OUT HMENU &hMenu, IN PCONFOLDPIDLVEC& cfpl, IN DWORD idCmdFirst)
  1030. {
  1031. TraceFileFunc(ttidMenus);
  1032. HRESULT hr = S_OK;
  1033. Assert(hMenu)
  1034. if (!hMenu)
  1035. {
  1036. return E_INVALIDARG;
  1037. }
  1038. int cMenuItems = GetMenuItemCount(hMenu);
  1039. for (int x = 0; x < cMenuItems; x++)
  1040. {
  1041. UINT nMenuID = GetMenuItemID(hMenu, x);
  1042. // UINT uiState = GetMenuState(hMenu, nMenuID, MF_BYCOMMAND );
  1043. NCCS_STATE nccs;
  1044. DWORD dwCustomResourceId = 0;
  1045. DWORD dwCmdId = NCCMDFromSFV(nMenuID, idCmdFirst) - idCmdFirst;
  1046. hr = HrGetCommandState(cfpl, dwCmdId, nccs, &dwCustomResourceId, 0xffffffff, NB_FLAG_ON_TOPMENU);
  1047. if (SUCCEEDED(hr))
  1048. {
  1049. if (nccs == NCCS_NOTSHOWN)
  1050. {
  1051. #ifdef DBG
  1052. WCHAR szTemp[MAX_PATH];
  1053. GetMenuStringW(hMenu, x, szTemp, MAX_PATH, MF_BYPOSITION );
  1054. TraceTag(ttidMenus, "Received request to permanently remove menu item: '%S' for CMDID: %d MenuID: %d", szTemp, dwCmdId, nMenuID);
  1055. #endif
  1056. RemoveMenu(hMenu, x, MF_BYPOSITION);
  1057. }
  1058. else
  1059. {
  1060. EnableMenuItem(
  1061. hMenu,
  1062. x,
  1063. nccs == NCCS_ENABLED ?
  1064. MF_ENABLED | MF_BYPOSITION: // enable
  1065. MF_GRAYED | MF_BYPOSITION);
  1066. }
  1067. }
  1068. NCCS_CHECKED_STATE nccCheckedState;
  1069. hr = HrGetCheckState(cfpl, dwCmdId, nccCheckedState);
  1070. if (S_OK == hr) // don't need to set if not supported on this item (S_FALSE)
  1071. {
  1072. CheckMenuItem(
  1073. hMenu,
  1074. x,
  1075. nccCheckedState == NCCS_CHECKED ?
  1076. MF_CHECKED | MF_BYPOSITION : // checked
  1077. MF_UNCHECKED | MF_BYPOSITION); // unchecked
  1078. }
  1079. }
  1080. return hr;
  1081. }
  1082. //+---------------------------------------------------------------------------
  1083. //
  1084. // Member: HasPermissionToRenameConnection
  1085. //
  1086. // Purpose: Checks if the Thread Local user has access to rename a given
  1087. // connection
  1088. //
  1089. // Arguments:
  1090. // [in] pcfp PIDL that wants to be renamed
  1091. //
  1092. // Returns:
  1093. // TRUE if has permissions
  1094. // FALSE if no permissions
  1095. //
  1096. // Author: deonb 8 Feb 2001
  1097. //
  1098. // Notes:
  1099. // ISSUE: Move out of this file
  1100. //
  1101. BOOL HasPermissionToRenameConnection(const PCONFOLDPIDL& pcfp)
  1102. {
  1103. TraceFileFunc(ttidMenus);
  1104. BOOL fPermission = FALSE;
  1105. // ISSUE: Due to a clarification in the spec this code is unreasonably complex.
  1106. // If possible clean it up in the future.
  1107. if (((!(pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
  1108. FHasPermissionFromCache(NCPERM_RenameMyRasConnection))))
  1109. {
  1110. fPermission = TRUE;
  1111. }
  1112. else if (FIsPolicyConfigured(NCPERM_RenameConnection))
  1113. {
  1114. if (((!(pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
  1115. FHasPermissionFromCache(NCPERM_RenameMyRasConnection))))
  1116. {
  1117. fPermission = TRUE;
  1118. }
  1119. else if ((pcfp->ncm != NCM_LAN) && (pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
  1120. FHasPermissionFromCache(NCPERM_RenameConnection) ||
  1121. (pcfp->ncm == NCM_LAN) && FHasPermissionFromCache(NCPERM_RenameConnection))
  1122. {
  1123. fPermission = TRUE;
  1124. }
  1125. }
  1126. else if (((pcfp->ncm == NCM_LAN) && FHasPermissionFromCache(NCPERM_RenameLanConnection))
  1127. || ((pcfp->ncm != NCM_LAN) && (pcfp->dwCharacteristics & NCCF_ALL_USERS) &&
  1128. FHasPermissionFromCache(NCPERM_RenameAllUserRasConnection)))
  1129. {
  1130. fPermission = TRUE;
  1131. }
  1132. return fPermission;
  1133. }
  1134. //+---------------------------------------------------------------------------
  1135. //
  1136. // Function: SetConnectMenuItem
  1137. //
  1138. // Purpose: This function goes in and modifies the first menu item so
  1139. // that it shows the correct test based on the connection
  1140. // state (enabled or not) or the connection type (LAN / WAN).
  1141. //
  1142. // Arguments:
  1143. // hmenu [in] Menu to operate on
  1144. // bLan [in] Whether or not this is a LAN connection
  1145. // idCmdFirst [in] Are commands are really an offset to this value
  1146. // bEnable [in] If the connection is enabled or not
  1147. //
  1148. // Returns:
  1149. //
  1150. // Author: mbend 8 Mar 2000
  1151. //
  1152. // Notes:
  1153. //
  1154. VOID SetConnectMenuItem(
  1155. HMENU hmenu,
  1156. BOOL bLan,
  1157. INT idCmdFirst,
  1158. BOOL bEnable)
  1159. {
  1160. // Different strings for WAN/LAN
  1161. INT iEnableString =
  1162. bLan ? IDS_DISABLE_MENUITEM : IDS_DISCONNECT_MENUITEM;
  1163. INT iDisableString =
  1164. bLan ? IDS_ENABLE_MENUITEM : IDS_CONNECT_MENUITEM;
  1165. INT iMenuString =
  1166. bEnable ? iEnableString : iDisableString;
  1167. PCWSTR pszMenuString = SzLoadIds(iMenuString);
  1168. MENUITEMINFO mii;
  1169. // Different commands for WAN/LAN
  1170. INT iConnect = bLan ? CMIDM_ENABLE : CMIDM_CONNECT;
  1171. INT iDisconnect = bLan ? CMIDM_DISABLE : CMIDM_DISCONNECT;
  1172. INT iOffset = bEnable ? iDisconnect : iConnect;
  1173. INT iNewCommand = idCmdFirst + iOffset;
  1174. Assert(pszMenuString);
  1175. // Set the menuitem fields
  1176. //
  1177. mii.cbSize = sizeof(MENUITEMINFO);
  1178. mii.fMask = MIIM_TYPE | MIIM_ID;
  1179. mii.fType = MFT_STRING;
  1180. mii.dwTypeData = (PWSTR) pszMenuString;
  1181. mii.wID = iNewCommand;
  1182. // This is assuming that we want to take out the first menu item.
  1183. if (!SetMenuItemInfo(hmenu, 0, TRUE, &mii))
  1184. {
  1185. TraceTag(ttidMenus, "SetMenuItemInfo returned: 0x%08x for CMIDM_DISCONNECT",
  1186. GetLastError());
  1187. }
  1188. }
  1189. //+---------------------------------------------------------------------------
  1190. //
  1191. // Function: HrSetConnectDisconnectMenuItem
  1192. //
  1193. // Purpose: Modify the menu item (if necessary) for connect/disconnect.
  1194. // We change this back and forth as needed since only one can be
  1195. // supported at a time, and those in charge don't want both
  1196. // appearing at any given time.
  1197. //
  1198. // Arguments:
  1199. // apidlSelected [in] List of selected objects
  1200. // cPidl [in] Count of selected objects
  1201. // hmenu [in] Our menu handle
  1202. //
  1203. // Returns:
  1204. //
  1205. // Author: jeffspr 1 May 1998
  1206. //
  1207. // Notes:
  1208. //
  1209. HRESULT HrSetConnectDisconnectMenuItem(
  1210. const PCONFOLDPIDLVEC& apidlSelected,
  1211. HMENU hmenu,
  1212. INT idCmdFirst)
  1213. {
  1214. HRESULT hr = S_OK;
  1215. if (apidlSelected.size() == 1)
  1216. {
  1217. Assert(!apidlSelected[0].empty() );
  1218. const PCONFOLDPIDL& pcfp = apidlSelected[0];
  1219. switch(pcfp->ncs)
  1220. {
  1221. case NCS_CONNECTED:
  1222. case NCS_DISCONNECTING:
  1223. case NCS_MEDIA_DISCONNECTED:
  1224. case NCS_INVALID_ADDRESS:
  1225. case NCS_AUTHENTICATING:
  1226. case NCS_AUTHENTICATION_FAILED:
  1227. case NCS_AUTHENTICATION_SUCCEEDED:
  1228. case NCS_CREDENTIALS_REQUIRED:
  1229. SetConnectMenuItem(hmenu, IsMediaLocalType(pcfp->ncm), idCmdFirst, TRUE);
  1230. break;
  1231. case NCS_DISCONNECTED:
  1232. case NCS_CONNECTING:
  1233. case NCS_HARDWARE_NOT_PRESENT:
  1234. case NCS_HARDWARE_DISABLED:
  1235. case NCS_HARDWARE_MALFUNCTION:
  1236. SetConnectMenuItem(hmenu, IsMediaLocalType(pcfp->ncm), idCmdFirst, FALSE);
  1237. break;
  1238. default:
  1239. AssertSz(FALSE, "HrSetConnectDisconnectMenuItem: What in the heck state is this?");
  1240. break;
  1241. }
  1242. }
  1243. TraceHr(ttidMenus, FAL, hr, FALSE, "HrSetConnectDisconnectMenuItem");
  1244. return hr;
  1245. }
  1246. HRESULT HrCanRenameConnection(
  1247. IN const CConFoldEntry& cfe,
  1248. IN BOOL fMultiSelect,
  1249. IN int iCommandId,
  1250. OUT NCCS_STATE& nccs
  1251. )
  1252. {
  1253. if (cfe.empty())
  1254. {
  1255. return S_FALSE;
  1256. }
  1257. if (cfe.GetCharacteristics() & NCCF_INCOMING_ONLY)
  1258. {
  1259. if (cfe.GetNetConMediaType() == NCM_NONE) // Incoming server - don't care
  1260. {
  1261. return S_FALSE;
  1262. }
  1263. else
  1264. {
  1265. nccs = NCCS_NOTSHOWN;
  1266. return S_OK;
  1267. }
  1268. }
  1269. else
  1270. {
  1271. CPConFoldPidl<ConFoldPidl_v2> pcfp;
  1272. cfe.ConvertToPidl(pcfp);
  1273. if (!HasPermissionToRenameConnection(pcfp))
  1274. {
  1275. nccs = NCCS_DISABLED;
  1276. }
  1277. else
  1278. {
  1279. return S_FALSE;
  1280. }
  1281. return S_OK;
  1282. }
  1283. }
  1284. HRESULT HrCanShowProperties(
  1285. IN const CConFoldEntry& cfe,
  1286. IN BOOL fMultiSelect,
  1287. IN int iCommandId,
  1288. OUT NCCS_STATE& nccs
  1289. )
  1290. {
  1291. if (cfe.empty())
  1292. {
  1293. return S_FALSE;
  1294. }
  1295. if (cfe.GetCharacteristics() & NCCF_INCOMING_ONLY)
  1296. {
  1297. if (cfe.GetNetConMediaType() == NCM_NONE) // Incoming server - don't care
  1298. {
  1299. return S_FALSE;
  1300. }
  1301. else
  1302. {
  1303. nccs = NCCS_NOTSHOWN;
  1304. return S_OK;
  1305. }
  1306. }
  1307. return S_FALSE;
  1308. }
  1309. BOOL IsBridgeInstalled()
  1310. {
  1311. BOOL fBridgePresent = FALSE; // fail to false
  1312. HRESULT hResult;
  1313. IHNetCfgMgr* pHomeNetConfigManager;
  1314. hResult = HrCreateInstance(CLSID_HNetCfgMgr, CLSCTX_INPROC, &pHomeNetConfigManager);
  1315. if(SUCCEEDED(hResult))
  1316. {
  1317. IHNetBridgeSettings* pNetBridgeSettings;
  1318. hResult = pHomeNetConfigManager->QueryInterface(IID_IHNetBridgeSettings, reinterpret_cast<void**>(&pNetBridgeSettings));
  1319. if(SUCCEEDED(hResult))
  1320. {
  1321. IHNetBridge* pNetBridge;
  1322. IEnumHNetBridges* pNetBridgeEnum;
  1323. hResult = pNetBridgeSettings->EnumBridges(&pNetBridgeEnum);
  1324. if(SUCCEEDED(hResult))
  1325. {
  1326. hResult = pNetBridgeEnum->Next(1, &pNetBridge, NULL);
  1327. if(S_OK == hResult)
  1328. {
  1329. fBridgePresent = TRUE;
  1330. ReleaseObj(pNetBridge);
  1331. }
  1332. ReleaseObj(pNetBridgeEnum);
  1333. }
  1334. ReleaseObj(pNetBridgeSettings);
  1335. }
  1336. ReleaseObj(pHomeNetConfigManager);
  1337. }
  1338. return fBridgePresent;
  1339. }
  1340. HRESULT HrIsBridgeSupported(
  1341. IN const CConFoldEntry& cfe,
  1342. IN BOOL fMultiSelect,
  1343. IN int iCommandId,
  1344. OUT NCCS_STATE& nccs
  1345. )
  1346. {
  1347. // if (cfe.empty())
  1348. // {
  1349. // return S_FALSE;
  1350. // }
  1351. //
  1352. #ifdef _WIN64
  1353. // Homenet technologies are not available at all on IA64
  1354. nccs = NCCS_NOTSHOWN;
  1355. return S_OK;
  1356. #else
  1357. // If the machine is Advanced server or data center, delete the bridge menu item
  1358. OSVERSIONINFOEXW verInfo = {0};
  1359. ULONGLONG ConditionMask = 0;
  1360. verInfo.dwOSVersionInfoSize = sizeof(verInfo);
  1361. verInfo.wSuiteMask = VER_SUITE_ENTERPRISE;
  1362. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
  1363. if (VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask))
  1364. {
  1365. nccs = NCCS_NOTSHOWN;
  1366. return S_OK;
  1367. }
  1368. else
  1369. {
  1370. BOOL fUserIsAdmin = FALSE;
  1371. HRESULT hr = S_OK;
  1372. CComPtr<INetConnectionUiUtilities> pConnectionUi;
  1373. hr = CoCreateInstance(CLSID_NetConnectionUiUtilities, NULL, CLSCTX_INPROC,
  1374. IID_INetConnectionUiUtilities, reinterpret_cast<void**>(&pConnectionUi));
  1375. if (FAILED(hr))
  1376. {
  1377. return hr;
  1378. }
  1379. fUserIsAdmin = FIsUserAdmin();
  1380. if (IsBridgeInstalled())
  1381. {
  1382. if (CMIDM_CREATE_BRIDGE == iCommandId)
  1383. {
  1384. nccs = NCCS_NOTSHOWN;
  1385. return S_OK;
  1386. }
  1387. else if (CMIDM_CONMENU_CREATE_BRIDGE == iCommandId)
  1388. {
  1389. nccs = NCCS_DISABLED;
  1390. return S_OK;
  1391. }
  1392. else // CMIDM_ADD_TO_BRIDGE or CMID_REMOVE_FROM_BRIDGE
  1393. {
  1394. if (!fUserIsAdmin || !pConnectionUi->UserHasPermission(NCPERM_AllowNetBridge_NLA))
  1395. {
  1396. nccs = NCCS_DISABLED;
  1397. return S_OK;
  1398. }
  1399. else
  1400. {
  1401. return S_FALSE; // Leave alone
  1402. }
  1403. }
  1404. }
  1405. else
  1406. {
  1407. if ( (CMIDM_CREATE_BRIDGE == iCommandId) ||
  1408. (CMIDM_CONMENU_CREATE_BRIDGE == iCommandId) )
  1409. {
  1410. if (!fUserIsAdmin || !pConnectionUi->UserHasPermission(NCPERM_AllowNetBridge_NLA))
  1411. {
  1412. nccs = NCCS_DISABLED;
  1413. return S_OK;
  1414. }
  1415. else
  1416. {
  1417. return S_FALSE; // Leave alone
  1418. }
  1419. }
  1420. else // CMIDM_ADD_TO_BRIDGE or CMID_REMOVE_FROM_BRIDGE
  1421. {
  1422. nccs = NCCS_NOTSHOWN;
  1423. return S_OK;
  1424. }
  1425. }
  1426. }
  1427. #endif
  1428. }
  1429. HRESULT HrOsIsLikePersonal()
  1430. {
  1431. if (IsOS(OS_PERSONAL))
  1432. {
  1433. return S_OK;
  1434. }
  1435. if (IsOS(OS_PROFESSIONAL))
  1436. {
  1437. LPWSTR pszDomain;
  1438. NETSETUP_JOIN_STATUS njs = NetSetupUnknownStatus;
  1439. if (NERR_Success == NetGetJoinInformation(NULL, &pszDomain, &njs))
  1440. {
  1441. NetApiBufferFree(pszDomain);
  1442. }
  1443. if (NetSetupDomainName == njs)
  1444. {
  1445. return S_FALSE; // connected to domain
  1446. }
  1447. else
  1448. {
  1449. return S_OK; // Professional, but not a domain member
  1450. }
  1451. }
  1452. return S_FALSE; // not personal or non-domain professional
  1453. }
  1454. HRESULT HrShouldHaveHomeNetWizard()
  1455. {
  1456. #ifdef _WIN64
  1457. return S_FALSE;
  1458. #else
  1459. if ( ( HrOsIsLikePersonal() == S_OK ) &&
  1460. FIsUserAdmin())
  1461. {
  1462. return S_OK;
  1463. }
  1464. else
  1465. {
  1466. return S_FALSE;
  1467. }
  1468. #endif
  1469. }
  1470. HRESULT HrIsHomeNewWizardSupported(
  1471. IN const CConFoldEntry& cfe,
  1472. IN BOOL fMultiSelect,
  1473. IN int iCommandId,
  1474. OUT NCCS_STATE& nccs
  1475. )
  1476. {
  1477. if (S_OK == HrShouldHaveHomeNetWizard() )
  1478. {
  1479. nccs = NCCS_ENABLED;
  1480. return S_OK;
  1481. }
  1482. else
  1483. {
  1484. nccs = NCCS_NOTSHOWN;
  1485. return S_OK;
  1486. }
  1487. }
  1488. HRESULT HrIsTroubleShootSupported(
  1489. IN const CConFoldEntry& cfe,
  1490. IN BOOL fMultiSelect,
  1491. IN int iCommandId,
  1492. OUT NCCS_STATE& nccs
  1493. )
  1494. {
  1495. if ( cfe.empty() && (!fMultiSelect) )
  1496. {
  1497. if ( ! IsOS(OS_ANYSERVER) )
  1498. {
  1499. nccs = NCCS_ENABLED;
  1500. return S_OK;
  1501. }
  1502. else
  1503. {
  1504. nccs = NCCS_ENABLED;
  1505. return S_OK;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. nccs = NCCS_DISABLED;
  1511. return S_OK;
  1512. }
  1513. }
  1514. HRESULT HrIsNCWSupported(
  1515. IN const CConFoldEntry& cfe,
  1516. IN BOOL fMultiSelect,
  1517. IN int iCommandId,
  1518. OUT NCCS_STATE& nccs
  1519. )
  1520. {
  1521. if ( (HrOsIsLikePersonal() == S_OK) &&
  1522. !FIsUserAdmin() )
  1523. {
  1524. nccs = NCCS_NOTSHOWN;
  1525. return S_OK;
  1526. }
  1527. else
  1528. {
  1529. return S_FALSE;
  1530. }
  1531. }
  1532. HRESULT HrIsMediaWireless(
  1533. IN const CConFoldEntry& cfe,
  1534. IN BOOL fMultiSelect,
  1535. IN int iCommandId,
  1536. OUT NCCS_STATE& nccs
  1537. )
  1538. {
  1539. if (cfe.GetNetConSubMediaType() != NCSM_WIRELESS)
  1540. {
  1541. nccs = NCCS_NOTSHOWN;
  1542. return S_OK;
  1543. }
  1544. return S_FALSE; // Continue with processing
  1545. }