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

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