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.

1106 lines
34 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "nsbase.h"
  4. #include <nsres.h>
  5. #include "ncmisc.h"
  6. #include "foldres.h"
  7. #include "foldinc.h" // Standard shell\folder includes
  8. #include "connlist.h"
  9. #include "iconhandler.h"
  10. template <class E> class ENUM_IDI_MAP
  11. {
  12. public:
  13. E EnumEntry;
  14. int iIcon;
  15. };
  16. template <class E> int MapIconEnumToResourceID(const ENUM_IDI_MAP<E> IconEnumArray[], DWORD dwElems, const E EnumMatch)
  17. {
  18. if (0 == EnumMatch)
  19. {
  20. return 0;
  21. }
  22. for (DWORD x = 0; x < dwElems; x++)
  23. {
  24. if (EnumMatch == IconEnumArray[x].EnumEntry)
  25. {
  26. return IconEnumArray[x].iIcon;
  27. }
  28. }
  29. AssertSz(FALSE, "Could not map match to Icon enum array");
  30. return 0;
  31. };
  32. static const ENUM_IDI_MAP<ENUM_STAT_ICON> c_STATUS_ICONS[] =
  33. {
  34. ICO_STAT_FAULT, IDI_CFI_STAT_FAULT,
  35. ICO_STAT_INVALID_IP, IDI_CFI_STAT_QUESTION,
  36. ICO_STAT_EAPOL_FAILED, IDI_CFI_STAT_QUESTION
  37. };
  38. static const ENUM_IDI_MAP<ENUM_CHARACTERISTICS_ICON> c_CHARACTERISTICS_ICON[] =
  39. {
  40. ICO_CHAR_INCOMING, IDI_OVL_INCOMING,
  41. ICO_CHAR_DEFAULT, IDI_OVL_DEFAULT,
  42. ICO_CHAR_FIREWALLED, IDI_OVL_FIREWALLED,
  43. ICO_CHAR_SHARED, IDI_OVL_SHARED,
  44. };
  45. static const ENUM_IDI_MAP<ENUM_CONNECTION_ICON> c_CONNECTION_ICONS[] =
  46. {
  47. ICO_CONN_BOTHOFF, IDI_CFI_CONN_ALLOFF,
  48. ICO_CONN_RIGHTON, IDI_CFI_CONN_RIGHTON,
  49. ICO_CONN_LEFTON, IDI_CFI_CONN_LEFTON,
  50. ICO_CONN_BOTHON, IDI_CFI_CONN_BOTHON,
  51. };
  52. struct NC_MEDIATYPE_ICON
  53. {
  54. DWORD ncm; // NETCON_MEDIATYPE (Shifted left by SHIFT_NETCON_MEDIATYPE)
  55. DWORD ncsm; // NETCON_SUBMEDIATYPE (Shifted left by SHIFT_NETCON_SUBMEDIATYPE)
  56. DWORD dwMasksSupported;
  57. INT iIcon;
  58. INT iIconDisabled; // Only for dwMasksSupported == MASK_NO_CONNECTIONOVERLAY
  59. };
  60. static const NC_MEDIATYPE_ICON c_NCM_ICONS[] =
  61. {
  62. // NETCON_MEDIATYPE (Shifted left by SHIFT_NETCON_MEDIATYPE)
  63. // | NETCON_SUBMEDIATYPE (Shifted left by SHIFT_NETCON_SUBMEDIATYPE (0) )
  64. // | | dwMasksSupported
  65. // | | | iIcon
  66. // | | | | Disabled Icon
  67. // | | | | | (for MASK_NO_CONNECTIONOVERLAY)
  68. // v v v v v
  69. NCM_NONE << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_NO_CONNECTIONOVERLAY, IDI_CFI_RASSERVER, IDI_CFI_RASSERVER,
  70. NCM_BRIDGE << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_STATUSOVERLAY, IDI_CFI_BRIDGE_CONNECTED, IDI_CFI_BRIDGE_DISCONNECTED,
  71. NCM_SHAREDACCESSHOST_LAN << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_NO_CONNECTIONOVERLAY, IDI_CFI_SAH_LAN, IDI_CFI_SAH_LAN,
  72. NCM_SHAREDACCESSHOST_RAS << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_NO_CONNECTIONOVERLAY, IDI_CFI_SAH_RAS, IDI_CFI_SAH_RAS,
  73. NCM_DIRECT << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_SUPPORT_ALL, IDI_CFI_DIRECT, 0,
  74. NCM_DIRECT << SHIFT_NETCON_MEDIATYPE, NCSM_DIRECT, MASK_SUPPORT_ALL, IDI_CFI_DIRECT, 0,
  75. NCM_DIRECT << SHIFT_NETCON_MEDIATYPE, NCSM_IRDA, MASK_SUPPORT_ALL, IDI_CFI_DIRECT, 0,
  76. NCM_ISDN << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_SUPPORT_ALL, IDI_CFI_ISDN, 0,
  77. NCM_LAN << SHIFT_NETCON_MEDIATYPE, NCSM_1394, MASK_SUPPORT_ALL, IDI_CFI_LAN, 0,
  78. NCM_LAN << SHIFT_NETCON_MEDIATYPE, NCSM_ATM, MASK_SUPPORT_ALL, IDI_CFI_LAN, 0,
  79. NCM_LAN << SHIFT_NETCON_MEDIATYPE, NCSM_ELAN, MASK_SUPPORT_ALL, IDI_CFI_LAN, 0,
  80. NCM_LAN << SHIFT_NETCON_MEDIATYPE, NCSM_LAN, MASK_SUPPORT_ALL, IDI_CFI_LAN, 0,
  81. NCM_LAN << SHIFT_NETCON_MEDIATYPE, NCSM_WIRELESS,MASK_SUPPORT_ALL, IDI_CFI_WIRELESS, 0,
  82. NCM_PPPOE << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_SUPPORT_ALL, IDI_CFI_PPPOE, 0,
  83. NCM_PHONE << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_SUPPORT_ALL, IDI_CFI_PHONE, 0,
  84. NCM_PHONE << SHIFT_NETCON_MEDIATYPE, NCSM_CM, MASK_SUPPORT_ALL, IDI_CFI_CM, 0,
  85. NCM_TUNNEL << SHIFT_NETCON_MEDIATYPE, NCSM_NONE, MASK_SUPPORT_ALL, IDI_CFI_VPN, 0,
  86. NCM_TUNNEL << SHIFT_NETCON_MEDIATYPE, NCSM_CM, MASK_SUPPORT_ALL, IDI_CFI_CM, 0,
  87. };
  88. struct NC_STATUS_ICON
  89. {
  90. NETCON_STATUS ncs;
  91. DWORD dwStatIcon;
  92. ENUM_CONNECTION_ICON enumConnectionIcon;
  93. };
  94. static const NC_STATUS_ICON c_NCS_ICONS[] =
  95. {
  96. // NETCON_STATUS
  97. // | dwStatIcon
  98. // | | enumConnectionIcon
  99. // | | |
  100. // v v v
  101. NCS_AUTHENTICATING, ICO_STAT_NONE, ICO_CONN_BOTHON,
  102. NCS_AUTHENTICATION_SUCCEEDED, ICO_STAT_NONE, ICO_CONN_BOTHON,
  103. NCS_AUTHENTICATION_FAILED, ICO_STAT_EAPOL_FAILED, ICO_CONN_BOTHON,
  104. NCS_CREDENTIALS_REQUIRED, ICO_STAT_EAPOL_FAILED, ICO_CONN_BOTHON,
  105. NCS_CONNECTED, ICO_STAT_NONE, ICO_CONN_BOTHON,
  106. NCS_DISCONNECTING, ICO_STAT_NONE, ICO_CONN_BOTHON,
  107. NCS_CONNECTING, ICO_STAT_DISABLED | ICO_STAT_NONE, ICO_CONN_BOTHOFF,
  108. NCS_DISCONNECTED, ICO_STAT_DISABLED | ICO_STAT_NONE, ICO_CONN_BOTHOFF,
  109. NCS_INVALID_ADDRESS, ICO_STAT_INVALID_IP, ICO_CONN_BOTHON,
  110. NCS_HARDWARE_DISABLED, ICO_STAT_FAULT, ICO_CONN_BOTHON,
  111. NCS_HARDWARE_MALFUNCTION, ICO_STAT_FAULT, ICO_CONN_BOTHON,
  112. NCS_HARDWARE_NOT_PRESENT, ICO_STAT_FAULT, ICO_CONN_BOTHON,
  113. NCS_MEDIA_DISCONNECTED, ICO_STAT_FAULT, ICO_CONN_BOTHON,
  114. };
  115. //+---------------------------------------------------------------------------
  116. //
  117. // Function: CNetConfigIcons::CNetConfigIcons
  118. //
  119. // Purpose: CNetConfigIcons constructor
  120. //
  121. // Arguments:
  122. // none
  123. //
  124. // Returns:
  125. // none
  126. //
  127. // Author: deonb 18 Feb 2001
  128. //
  129. // Notes:
  130. //
  131. CNetConfigIcons::CNetConfigIcons(IN HINSTANCE hInstance) : m_hInstance(hInstance)
  132. {
  133. TraceFileFunc(ttidIcons);
  134. dwLastBrandedId = 0;
  135. InitializeCriticalSection(&csNetConfigIcons);
  136. }
  137. //+---------------------------------------------------------------------------
  138. //
  139. // Function: CNetConfigIcons::~CNetConfigIcons
  140. //
  141. // Purpose: CNetConfigIcons destructor
  142. //
  143. // Arguments:
  144. // none
  145. //
  146. // Returns:
  147. // none
  148. //
  149. // Author: deonb 18 Feb 2001
  150. //
  151. // Notes:
  152. //
  153. CNetConfigIcons::~CNetConfigIcons()
  154. {
  155. // Can't trace in this function!
  156. IMAGELISTMAP::iterator iter;
  157. for (iter = m_ImageLists.begin(); iter != m_ImageLists.end(); iter++)
  158. {
  159. HIMAGELIST hImageLst = iter->second;
  160. ImageList_Destroy(hImageLst);
  161. }
  162. m_ImageLists.clear();
  163. DeleteCriticalSection(&csNetConfigIcons);
  164. }
  165. //+---------------------------------------------------------------------------
  166. //
  167. // Function: CNetConfigIcons::HrMergeTwoIcons
  168. //
  169. // Purpose: Merge a new icon unto an existing one
  170. //
  171. // Arguments:
  172. // dwIconSize [in] Size of the icon
  173. // phMergedIcon [in out] Icon 1 to merge, and contains the merged
  174. // icon on output
  175. // hIconToMerge [in] Icon 2 to merge with
  176. //
  177. // Returns:
  178. // HRESULT
  179. //
  180. // Author: deonb 4 Apr 2001
  181. //
  182. // Notes:
  183. //
  184. HRESULT CNetConfigIcons::HrMergeTwoIcons(IN DWORD dwIconSize, IN OUT HICON *phMergedIcon, IN HICON hIconToMergeWith)
  185. {
  186. HRESULT hr = S_FALSE;
  187. Assert(phMergedIcon);
  188. HIMAGELIST hImageLst = NULL;
  189. IMAGELISTMAP::iterator i = m_ImageLists.find(dwIconSize);
  190. if (i == m_ImageLists.end())
  191. {
  192. hImageLst = ImageList_Create(dwIconSize, dwIconSize, ILC_COLOR32 | ILC_MASK, 2, 0);
  193. if (hImageLst)
  194. {
  195. m_ImageLists[dwIconSize] = hImageLst;
  196. }
  197. else
  198. {
  199. hr = E_FAIL;
  200. }
  201. }
  202. else
  203. {
  204. hImageLst = i->second;
  205. }
  206. if (SUCCEEDED(hr))
  207. {
  208. if (*phMergedIcon)
  209. {
  210. if (hIconToMergeWith)
  211. {
  212. hr = E_FAIL;
  213. // Merge the 2 icons;
  214. if (ImageList_RemoveAll(hImageLst))
  215. {
  216. int iIcon1 = ImageList_AddIcon(hImageLst, *phMergedIcon);
  217. if (-1 != iIcon1)
  218. {
  219. int iIcon2 = ImageList_AddIcon(hImageLst, hIconToMergeWith);
  220. if (-1 != iIcon2)
  221. {
  222. if (ImageList_SetOverlayImage(hImageLst, iIcon2, 1))
  223. {
  224. DestroyIcon(*phMergedIcon); // Delete the current icon
  225. *phMergedIcon = ImageList_GetIcon(hImageLst, iIcon1, INDEXTOOVERLAYMASK(1));
  226. hr = S_OK;
  227. }
  228. }
  229. }
  230. }
  231. }
  232. // else Nothing. Stays the same.
  233. }
  234. else
  235. {
  236. // Copy icon 2 to icon 1
  237. *phMergedIcon = CopyIcon(hIconToMergeWith);
  238. }
  239. }
  240. return hr;
  241. };
  242. //+---------------------------------------------------------------------------
  243. //
  244. // Function: CNetConfigIcons::HrGetInternalIconIDForPIDL
  245. //
  246. // Purpose: Map the connection state and connection type to the
  247. // appropriate icon resource IDs.
  248. //
  249. // Arguments:
  250. // uFlags [in] The GIL_xxx shell flags
  251. // cfe [in] The connection folder entry
  252. // dwIcon [out] The ID of the icon
  253. //
  254. // Returns:
  255. // HRESULT
  256. //
  257. // Author: deonb 18 Feb 2001
  258. //
  259. // Notes:
  260. //
  261. HRESULT CNetConfigIcons::HrGetInternalIconIDForPIDL(IN UINT uFlags, IN const CConFoldEntry& cfe, OUT DWORD& dwIcon)
  262. {
  263. TraceFileFunc(ttidIcons);
  264. if (cfe.GetCharacteristics() & NCCF_BRANDED)
  265. {
  266. AssertSz(FALSE, "Call HrGetBrandedIconIDForPIDL instead for branded icons");
  267. return E_INVALIDARG;
  268. }
  269. Assert(!cfe.empty());
  270. BOOL fValidIcon = FALSE;
  271. if (cfe.GetWizard() == WIZARD_MNC)
  272. {
  273. dwIcon = ICO_MGR_RESOURCEID | IDI_CONFOLD_WIZARD;
  274. fValidIcon = TRUE;
  275. }
  276. else if (cfe.GetWizard() == WIZARD_HNW)
  277. {
  278. dwIcon = ICO_MGR_RESOURCEID | IDI_CONFOLD_HOMENET_WIZARD;
  279. fValidIcon = TRUE;
  280. }
  281. else
  282. {
  283. dwIcon = ICO_MGR_INTERNAL;
  284. Assert(cfe.GetWizard() == WIZARD_NOT_WIZARD);
  285. const NETCON_SUBMEDIATYPE ncsm = cfe.GetNetConSubMediaType();
  286. const NETCON_MEDIATYPE ncm = cfe.GetNetConMediaType();
  287. const NETCON_STATUS ncs = cfe.GetNetConStatus();
  288. // Find the Status part of the icon
  289. for (DWORD dwLoop = 0; (dwLoop < celems(c_NCM_ICONS)); dwLoop++)
  290. {
  291. const NC_STATUS_ICON& ncsIcon = c_NCS_ICONS[dwLoop];
  292. if (ncs == ncsIcon.ncs)
  293. {
  294. Assert((ncsIcon.dwStatIcon & (MASK_STATUS | MASK_STATUS_DISABLED) ) == ncsIcon.dwStatIcon);
  295. Assert((ncsIcon.enumConnectionIcon & (MASK_CONNECTION) ) == ncsIcon.enumConnectionIcon);
  296. dwIcon |= ncsIcon.dwStatIcon;
  297. dwIcon |= ncsIcon.enumConnectionIcon;
  298. dwIcon |= ncm << SHIFT_NETCON_MEDIATYPE;
  299. dwIcon |= ncsm << SHIFT_NETCON_SUBMEDIATYPE;
  300. fValidIcon = TRUE;
  301. break;
  302. }
  303. }
  304. }
  305. AssertSz(fValidIcon, "Could not obtain an icon for this connection");
  306. if (fValidIcon)
  307. {
  308. return S_OK;
  309. }
  310. else
  311. {
  312. return E_FAIL;
  313. }
  314. }
  315. //+---------------------------------------------------------------------------
  316. //
  317. // Function: CNetConfigIcons::HrMergeCharacteristicsIcons
  318. //
  319. // Purpose: Merge the characteristics icons unto an input icon
  320. //
  321. // Arguments:
  322. // dwIconSize [in] Size of the icon
  323. // dwIconId [in] Icon ID (to read Characteristics info from)
  324. // phMergedIcon [in out] The icon to merge with, and contains the merged
  325. // icon on output
  326. //
  327. // Returns:
  328. // HRESULT
  329. //
  330. // Author: deonb 4 Apr 2001
  331. //
  332. // Notes:
  333. //
  334. HRESULT CNetConfigIcons::HrMergeCharacteristicsIcons(IN DWORD dwIconSize, IN DWORD dwIconId, IN OUT HICON *phMergedIcon)
  335. {
  336. HRESULT hr = S_OK;
  337. Assert(phMergedIcon);
  338. if (!(dwIconId & MASK_CHARACTERISTICS))
  339. {
  340. return S_FALSE;
  341. }
  342. // Characteristics
  343. int iFireWalled = MapIconEnumToResourceID(c_CHARACTERISTICS_ICON, celems(c_CHARACTERISTICS_ICON), static_cast<ENUM_CHARACTERISTICS_ICON>(dwIconId & ICO_CHAR_FIREWALLED));
  344. int iIncoming = MapIconEnumToResourceID(c_CHARACTERISTICS_ICON, celems(c_CHARACTERISTICS_ICON), static_cast<ENUM_CHARACTERISTICS_ICON>(dwIconId & ICO_CHAR_INCOMING));
  345. int iShared = MapIconEnumToResourceID(c_CHARACTERISTICS_ICON, celems(c_CHARACTERISTICS_ICON), static_cast<ENUM_CHARACTERISTICS_ICON>(dwIconId & ICO_CHAR_SHARED));
  346. int iDefault = MapIconEnumToResourceID(c_CHARACTERISTICS_ICON, celems(c_CHARACTERISTICS_ICON), static_cast<ENUM_CHARACTERISTICS_ICON>(dwIconId & ICO_CHAR_DEFAULT));
  347. HICON hFireWalled = iFireWalled ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iFireWalled), dwIconSize) : NULL;
  348. HICON hShared = iShared ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iShared), dwIconSize) : NULL;
  349. HICON hDefault = iDefault ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iDefault), dwIconSize) : NULL;
  350. HICON hIncoming = NULL;
  351. if (dwIconSize != GetSystemMetrics(SM_CXSMICON)) // Shouldn't display in 16x16
  352. {
  353. hIncoming = iIncoming ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iIncoming), dwIconSize) : NULL;
  354. AssertSz(FImplies(iIncoming, hIncoming), "Could not load the Incoming Icon");
  355. }
  356. AssertSz(FImplies(iFireWalled, hFireWalled), "Could not load the FireWalled Icon");
  357. AssertSz(FImplies(iShared, hShared), "Could not load the Shared Icon");
  358. AssertSz(FImplies(iDefault, hDefault), "Could not load the Default Icon");
  359. HICON hIconArray[] = {hFireWalled, hIncoming, hShared, hDefault};
  360. for (int x = 0; x < celems(hIconArray); x++)
  361. {
  362. hr = HrMergeTwoIcons(dwIconSize, phMergedIcon, hIconArray[x]);
  363. if (FAILED(hr))
  364. {
  365. break;
  366. }
  367. }
  368. for (int x = 0; x < celems(hIconArray); x++)
  369. {
  370. if (hIconArray[x])
  371. {
  372. DestroyIcon(hIconArray[x]);
  373. hIconArray[x] = NULL;
  374. }
  375. }
  376. AssertSz(SUCCEEDED(hr) && *phMergedIcon, "Could not load a characteristics icon");
  377. return hr;
  378. }
  379. //+---------------------------------------------------------------------------
  380. //
  381. // Function: CNetConfigIcons::HrGetInternalIconFromIconId
  382. //
  383. // Purpose: Loads the netshell internal icon given the icon ID
  384. // (from HrGetInternalIconIDForPIDL)
  385. //
  386. // Arguments:
  387. // dwIconSize [in] Size of the icon required
  388. // dwIconId [in] Icon ID - from HrGetInternalIconIDForPIDL
  389. // hIcon [in] The icon that was loaded
  390. //
  391. // Returns:
  392. // HRESULT
  393. //
  394. // Author: deonb 18 Feb 2001
  395. //
  396. // Notes:
  397. //
  398. HRESULT CNetConfigIcons::HrGetInternalIconFromIconId(IN DWORD dwIconSize, IN DWORD dwIconId, OUT HICON &hIcon)
  399. {
  400. TraceFileFunc(ttidIcons);
  401. DWORD dwlrFlags = 0;
  402. if ( (dwIconId & MASK_ICONMANAGER) != ICO_MGR_INTERNAL)
  403. {
  404. AssertSz(FALSE, "This is not an internal icon");
  405. return E_INVALIDARG;
  406. }
  407. HRESULT hr = E_FAIL;
  408. DWORD ncm = (dwIconId & MASK_NETCON_MEDIATYPE);
  409. DWORD ncsm = (dwIconId & MASK_NETCON_SUBMEDIATYPE);
  410. BOOL fDisabledStatus = (dwIconId & ICO_STAT_DISABLED);
  411. // Status & Connection
  412. int iStatus = MapIconEnumToResourceID(c_STATUS_ICONS, celems(c_STATUS_ICONS), static_cast<ENUM_STAT_ICON>(dwIconId & MASK_STATUS));
  413. int iConnection = MapIconEnumToResourceID(c_CONNECTION_ICONS, celems(c_CONNECTION_ICONS), static_cast<ENUM_CONNECTION_ICON>(dwIconId & MASK_CONNECTION));
  414. int iMediaType = 0;
  415. // Media Type
  416. for (int x = 0; x < celems(c_NCM_ICONS); x++)
  417. {
  418. const NC_MEDIATYPE_ICON& ncmIcon = c_NCM_ICONS[x];
  419. // Use NCSM if available, otherwise use NCM
  420. if ( ((NCSM_NONE == ncsm) && (NCSM_NONE == ncmIcon.ncsm) && (ncm == ncmIcon.ncm)) ||
  421. ((NCSM_NONE != ncsm) && (ncsm == ncmIcon.ncsm)) )
  422. {
  423. if (!(ncmIcon.dwMasksSupported & MASK_CONNECTION))
  424. {
  425. iConnection = 0;
  426. }
  427. if (!(ncmIcon.dwMasksSupported & MASK_STATUS))
  428. {
  429. iStatus = 0;
  430. }
  431. iMediaType = ncmIcon.iIcon;
  432. if (!(iConnection || iStatus) &&
  433. (fDisabledStatus))
  434. {
  435. Assert(ncmIcon.iIconDisabled);
  436. iMediaType = ncmIcon.iIconDisabled;
  437. }
  438. }
  439. }
  440. Assert(iMediaType);
  441. if (iMediaType)
  442. {
  443. HICON hMediaType = iMediaType ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iMediaType), dwIconSize) : NULL;
  444. HICON hStatus = iStatus ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iStatus), dwIconSize) : NULL;
  445. HICON hConnection = NULL;
  446. if (dwIconSize != GetSystemMetrics(SM_CXSMICON)) // Shouldn't display in 16x16
  447. {
  448. hConnection = iConnection ? LoadIconSize(m_hInstance, MAKEINTRESOURCE(iConnection), dwIconSize) : NULL;
  449. AssertSz(FImplies(iConnection, hConnection), "Could not load the Connection Icon");
  450. }
  451. AssertSz(FImplies(iMediaType, hMediaType), "Could not load the Media Type Icon");
  452. AssertSz(FImplies(iStatus, hStatus), "Could not load the Status Icon");
  453. HICON hIconArray[] = {hMediaType, hStatus, hConnection};
  454. hIcon = NULL;
  455. for (int x = 0; x < celems(hIconArray); x++)
  456. {
  457. hr = HrMergeTwoIcons(dwIconSize, &hIcon, hIconArray[x]);
  458. if (FAILED(hr))
  459. {
  460. break;
  461. }
  462. }
  463. for (int x = 0; x < celems(hIconArray); x++)
  464. {
  465. if (hIconArray[x])
  466. {
  467. DestroyIcon(hIconArray[x]);
  468. hIconArray[x] = NULL;
  469. }
  470. }
  471. if (SUCCEEDED(hr))
  472. {
  473. hr = HrMergeCharacteristicsIcons(dwIconSize, dwIconId, &hIcon);
  474. if (SUCCEEDED(hr))
  475. {
  476. hr = S_OK;
  477. }
  478. }
  479. }
  480. AssertSz(SUCCEEDED(hr) && hIcon, "Could not load any icon");
  481. return hr;
  482. }
  483. //+---------------------------------------------------------------------------
  484. //
  485. // Function: CNetConfigIcons::HrGetResourceIconFromIconId
  486. //
  487. // Purpose: Loads a resource icon given the icon ID
  488. // (from HrGetInternalIconIDForPIDL)
  489. //
  490. // Arguments:
  491. // dwIconSize [in] Size of the icon required
  492. // dwIconId [in] Icon ID - from HrGetInternalIconIDForPIDL
  493. // hIcon [in] The icon that was loaded
  494. //
  495. // Returns:
  496. // HRESULT
  497. //
  498. // Author: deonb 18 Feb 2001
  499. //
  500. // Notes:
  501. //
  502. HRESULT CNetConfigIcons::HrGetResourceIconFromIconId(IN DWORD dwIconSize, IN DWORD dwIconId, OUT HICON &hIcon)
  503. {
  504. TraceFileFunc(ttidIcons);
  505. DWORD dwlrFlags = 0;
  506. if ( (dwIconId & MASK_ICONMANAGER) != ICO_MGR_RESOURCEID)
  507. {
  508. AssertSz(FALSE, "This is not a resource id icon manager icon");
  509. return E_INVALIDARG;
  510. }
  511. HRESULT hr = S_OK;
  512. int iIcon = dwIconId & MASK_BRANDORRESOURCEID; // Clear the rest of the bits;
  513. hIcon = LoadIconSize(m_hInstance, MAKEINTRESOURCE(iIcon), dwIconSize);
  514. if (!hIcon)
  515. {
  516. hr = HRESULT_FROM_WIN32(GetLastError());
  517. }
  518. else
  519. {
  520. hr = HrMergeCharacteristicsIcons(dwIconSize, dwIconId, &hIcon);
  521. if (SUCCEEDED(hr))
  522. {
  523. hr = S_OK;
  524. }
  525. }
  526. TraceHr(ttidError, FAL, hr, FALSE, "Could not load icon %d (size %d x %d) from resource file", iIcon, dwIconSize, dwIconSize);
  527. return hr;
  528. }
  529. //+---------------------------------------------------------------------------
  530. //
  531. // Function: CNetConfigIcons::HrGetBrandedIconIDForPIDL
  532. //
  533. // Purpose: Initializes the branded icon info from a file
  534. //
  535. // Arguments:
  536. // uFlags [in] The GIL_xxx shell flags
  537. // cfe [in] The connection folder entry
  538. // dwIcon [out] The ID of the icon
  539. //
  540. // Returns:
  541. // HRESULT
  542. //
  543. // Author: deonb 18 Feb 2001
  544. //
  545. // Notes: We store this internally into a map - hence we can't cache
  546. // branded icons since we might not end up with the same id in the map
  547. //
  548. HRESULT CNetConfigIcons::HrGetBrandedIconIDForPIDL(IN UINT uFlags, IN const CConFoldEntry& cfe, OUT DWORD& dwIcon)
  549. {
  550. TraceFileFunc(ttidIcons);
  551. HRESULT hr = S_OK;
  552. if (!(cfe.GetCharacteristics() & NCCF_BRANDED))
  553. {
  554. AssertSz(FALSE, "Call HrGetInternalIconIDForPIDL instead for non-branded icons");
  555. return E_INVALIDARG;
  556. }
  557. Assert(!cfe.empty());
  558. if (cfe.GetWizard() != WIZARD_NOT_WIZARD)
  559. {
  560. AssertSz(FALSE, "You're not allowed to brand the wizard");
  561. hr = E_INVALIDARG;
  562. }
  563. else
  564. {
  565. dwIcon = ICO_MGR_CM;
  566. if (g_ccl.IsInitialized() == FALSE)
  567. {
  568. g_ccl.HrRefreshConManEntries();
  569. }
  570. ConnListEntry cle;
  571. hr = g_ccl.HrFindConnectionByGuid(&(cfe.GetGuidID()), cle);
  572. if (S_OK == hr)
  573. {
  574. tstring szBrandedFileName;
  575. BOOL bBrandedName = FALSE;
  576. if (cle.pcbi)
  577. {
  578. if (cle.pcbi->szwLargeIconPath)
  579. {
  580. szBrandedFileName = cle.pcbi->szwLargeIconPath;
  581. bBrandedName = TRUE;
  582. }
  583. else if (cle.pcbi->szwSmallIconPath)
  584. {
  585. szBrandedFileName = cle.pcbi->szwSmallIconPath;
  586. bBrandedName = TRUE;
  587. }
  588. }
  589. if (bBrandedName)
  590. {
  591. BrandedNames::const_iterator i = m_BrandedNames.find(szBrandedFileName);
  592. if (i == m_BrandedNames.end()) // Doesn't exist yet
  593. {
  594. dwLastBrandedId++;
  595. m_BrandedNames[szBrandedFileName] = dwLastBrandedId;
  596. dwIcon |= dwLastBrandedId;
  597. }
  598. else
  599. {
  600. dwIcon |= i->second;
  601. }
  602. }
  603. else
  604. {
  605. CConFoldEntry cfeTmp;
  606. cfeTmp = cfe;
  607. cfeTmp.SetCharacteristics(cfe.GetCharacteristics() & ~NCCF_BRANDED);
  608. cfeTmp.SetNetConSubMediaType(NCSM_CM);
  609. dwIcon = 0;
  610. hr = HrGetInternalIconIDForPIDL(uFlags, cfeTmp, dwIcon);
  611. }
  612. }
  613. else
  614. {
  615. hr = E_FILE_NOT_FOUND;
  616. }
  617. }
  618. TraceHr(ttidError, FAL, hr, FALSE, "Could not obtain an icon for this connection");
  619. return hr;
  620. }
  621. //+---------------------------------------------------------------------------
  622. //
  623. // Function: CNetConfigIcons::HrGetBrandedIconFromIconId
  624. //
  625. // Purpose: Loads the branded icon given the icon ID
  626. // (from HrGetBrandedIconIDForPIDL)
  627. //
  628. // Arguments:
  629. // dwIconSize [in] Size of the icon required
  630. // dwIconId [in] Icon ID - from HrGetBrandedIconIDForPIDL
  631. // hIcon [in] The icon that was loaded
  632. //
  633. // Returns:
  634. // HRESULT
  635. //
  636. // Author: deonb 18 Feb 2001
  637. //
  638. // Notes:
  639. //
  640. HRESULT CNetConfigIcons::HrGetBrandedIconFromIconId(IN DWORD dwIconSize, IN DWORD dwIconId, OUT HICON &hIcon)
  641. {
  642. TraceFileFunc(ttidIcons);
  643. if ( (dwIconId & MASK_ICONMANAGER) != ICO_MGR_CM)
  644. {
  645. AssertSz(FALSE, "This is not a branded icon");
  646. return E_INVALIDARG;
  647. }
  648. HRESULT hr = S_OK;
  649. DWORD dwIconIdTmp;
  650. dwIconIdTmp = dwIconId & MASK_BRANDORRESOURCEID;
  651. Assert(dwIconIdTmp);
  652. if (dwIconIdTmp)
  653. {
  654. BOOL bFound = FALSE;
  655. tstring szBrandedFileName;
  656. for (BrandedNames::iterator i = m_BrandedNames.begin(); i != m_BrandedNames.end(); i++)
  657. {
  658. if (i->second == dwIconIdTmp)
  659. {
  660. #ifdef DBG
  661. if (bFound)
  662. {
  663. AssertSz(FALSE, "Multiple icon IDs in branded table found");
  664. }
  665. #endif
  666. bFound = TRUE;
  667. szBrandedFileName = i->first;
  668. break;
  669. }
  670. }
  671. if (!bFound)
  672. {
  673. AssertSz(FALSE, "Branded icon id not found in branded table");
  674. return E_FAIL;
  675. }
  676. hIcon = static_cast<HICON>(LoadImage(
  677. NULL,
  678. szBrandedFileName.c_str(),
  679. IMAGE_ICON,
  680. dwIconSize, dwIconSize,
  681. LR_LOADFROMFILE));
  682. }
  683. if (!hIcon)
  684. {
  685. hr = HRESULT_FROM_WIN32(GetLastError());
  686. }
  687. else
  688. {
  689. hr = HrMergeCharacteristicsIcons(dwIconSize, dwIconId, &hIcon);
  690. if (SUCCEEDED(hr))
  691. {
  692. hr = S_OK;
  693. }
  694. }
  695. TraceHr(ttidError, FAL, hr, FALSE, "CNetConfigIcons::HrGetBrandedIconFromIconId");
  696. return hr;
  697. }
  698. //+---------------------------------------------------------------------------
  699. //
  700. // Function: CNetConfigIcons::HrGetIconIDForPIDL
  701. //
  702. // Purpose: Get a unique icon number given a Connection Folder Entry
  703. //
  704. // Arguments:
  705. // uFlags [in] The GIL_xxx shell flags
  706. // cfe [in] The connection folder entry
  707. // dwIcon [out] The ID of the icon
  708. // pfCanCache [out] Whether we can cache the icon
  709. //
  710. // Returns:
  711. // HRESULT
  712. //
  713. // Author: deonb 18 Feb 2001
  714. //
  715. // Notes:
  716. //
  717. HRESULT CNetConfigIcons::HrGetIconIDForPIDL(IN UINT uFlags, IN const CConFoldEntry& cfe, OUT DWORD& dwIconId, OUT LPBOOL pfCanCache)
  718. {
  719. TraceFileFunc(ttidIcons);
  720. CExceptionSafeLock EsLock(&csNetConfigIcons);
  721. HRESULT hr = S_OK;
  722. if (cfe.GetCharacteristics() & NCCF_BRANDED)
  723. {
  724. *pfCanCache = FALSE;
  725. hr = HrGetBrandedIconIDForPIDL(uFlags, cfe, dwIconId);
  726. }
  727. else
  728. {
  729. #ifdef DBG
  730. if (FIsDebugFlagSet(dfidDontCacheShellIcons))
  731. {
  732. *pfCanCache = FALSE;
  733. }
  734. else
  735. {
  736. *pfCanCache = TRUE;
  737. }
  738. #else
  739. *pfCanCache = TRUE;
  740. #endif
  741. hr = HrGetInternalIconIDForPIDL(uFlags, cfe, dwIconId);
  742. }
  743. if (FAILED(hr))
  744. {
  745. return hr;
  746. }
  747. Assert( (dwIconId & ~MASK_CHARACTERISTICS) == dwIconId); // Make sure we did't overflow into the overlay
  748. if (!(GIL_FORSHORTCUT & uFlags))
  749. {
  750. DWORD dwOverlay = 0;
  751. if ( (cfe.GetCharacteristics() & NCCF_INCOMING_ONLY) &&
  752. (cfe.GetNetConMediaType() != NCM_NONE) ) // No overlay for "default" incoming connection
  753. {
  754. dwIconId |= ICO_CHAR_INCOMING;
  755. }
  756. if (cfe.GetCharacteristics() & NCCF_SHARED)
  757. {
  758. dwIconId |= ICO_CHAR_SHARED;
  759. }
  760. if (cfe.GetCharacteristics() & NCCF_FIREWALLED)
  761. {
  762. dwIconId |= ICO_CHAR_FIREWALLED;
  763. }
  764. if (cfe.GetCharacteristics() & NCCF_DEFAULT)
  765. {
  766. dwIconId |= ICO_CHAR_DEFAULT;
  767. }
  768. }
  769. return hr;
  770. }
  771. //+---------------------------------------------------------------------------
  772. //
  773. // Function: CNetConfigIcons::HrGetIconFromIconId
  774. //
  775. // Purpose: Loads an icon given the icon ID (branded or internal)
  776. //
  777. // Arguments:
  778. // dwIconSize [in] Size of the icon required
  779. // dwIconId [in] Icon ID - from HrGetIconIDForPIDL
  780. // hIcon [in] The icon that was loaded
  781. //
  782. // Returns:
  783. //
  784. // Author: deonb 18 Feb 2001
  785. //
  786. // Notes:
  787. //
  788. HRESULT CNetConfigIcons::HrGetIconFromIconId(IN DWORD dwIconSize, IN DWORD dwIconId, OUT HICON &hIcon)
  789. {
  790. TraceFileFunc(ttidIcons);
  791. CExceptionSafeLock EsLock(&csNetConfigIcons);
  792. HRESULT hr = S_OK;
  793. switch (dwIconId & MASK_ICONMANAGER)
  794. {
  795. case ICO_MGR_CM:
  796. hr = HrGetBrandedIconFromIconId(dwIconSize, dwIconId, hIcon);
  797. break;
  798. case ICO_MGR_INTERNAL:
  799. hr = HrGetInternalIconFromIconId(dwIconSize, dwIconId, hIcon);
  800. break;
  801. case ICO_MGR_RESOURCEID:
  802. hr = HrGetResourceIconFromIconId(dwIconSize, dwIconId, hIcon);
  803. break;
  804. default:
  805. hr = E_INVALIDARG;
  806. AssertSz(FALSE, "Unknown Icon manager");
  807. break;
  808. }
  809. if (SUCCEEDED(hr))
  810. {
  811. DWORD dwOverlays = (dwIconId & MASK_CHARACTERISTICS); // get the mask bits
  812. }
  813. return hr;
  814. }
  815. //+---------------------------------------------------------------------------
  816. //
  817. // Function: CNetConfigIcons::HrGetIconFromIconId
  818. //
  819. // Purpose: Loads an icon given the icon ID (branded or internal)
  820. //
  821. // Arguments:
  822. // dwIconSize [in] Size of the icon required
  823. // ncm [in] The NETCON_MEDIATYPE
  824. // ncsm [in] The NETCON_SUBMEDIATYPE
  825. // dwConnectionIcon [in] ENUM_CONNECTION_ICON (Not shifted (IOW: 0 or 4,5,6,7)
  826. // dwCharacteristics [in] The NCCF_CHARACTERISTICS flag (0 allowed)
  827. // phIcon [in] The resulting icon. Destroy using DestroyIcon
  828. //
  829. // Returns:
  830. //
  831. // Author: deonb 23 Apr 2001
  832. //
  833. // Notes:
  834. //
  835. HRESULT CNetConfigIcons::HrGetIconFromMediaType(DWORD dwIconSize, IN NETCON_MEDIATYPE ncm, IN NETCON_SUBMEDIATYPE ncsm, IN DWORD dwConnectionIcon, IN DWORD dwCharacteristics, OUT HICON *phIcon)
  836. {
  837. HRESULT hr = S_OK;
  838. CConFoldEntry cfe;
  839. // Is this a request for a special folder icon?
  840. if ( (0xFFFFFFFF == dwCharacteristics) &&
  841. (NCM_NONE == ncm) &&
  842. (NCSM_NONE == ncsm)
  843. )
  844. {
  845. BOOL bFoundIcon = FALSE;
  846. int iIcon = 0;
  847. switch (dwConnectionIcon)
  848. {
  849. case 0x80000000:
  850. iIcon = IDI_CONNECTIONS_FOLDER_LARGE2;
  851. bFoundIcon = TRUE;
  852. break;
  853. case 0x80000001:
  854. iIcon = IDI_CONFOLD_WIZARD;
  855. bFoundIcon = TRUE;
  856. break;
  857. case 0x80000002:
  858. iIcon = IDI_CONFOLD_HOMENET_WIZARD;
  859. bFoundIcon = TRUE;
  860. break;
  861. }
  862. if (bFoundIcon)
  863. {
  864. *phIcon = LoadIconSize(_Module.GetResourceInstance(), MAKEINTRESOURCE(iIcon), dwIconSize);
  865. if (*phIcon)
  866. {
  867. return S_OK;
  868. }
  869. else
  870. {
  871. return HrFromLastWin32Error();
  872. }
  873. }
  874. }
  875. // No? Then load a media type icon
  876. NETCON_STATUS ncs;
  877. if (ICO_CONN_BOTHOFF == dwConnectionIcon)
  878. {
  879. ncs = NCS_DISCONNECTED;
  880. }
  881. else
  882. {
  883. ncs = NCS_CONNECTED;
  884. }
  885. // Most of these values (except for ncm, ncsm, ncs) are totally fake.
  886. // However, we need to initialize this structure with
  887. // something or it will assert on us.
  888. //
  889. // HrGetIconIDForPidl will only use ncm, ncsm, ncs & dwCharacteristics
  890. hr = cfe.HrInitData(WIZARD_NOT_WIZARD,
  891. ncm,
  892. ncsm,
  893. ncs,
  894. &(CLSID_ConnectionCommonUi), // FAKE
  895. &(CLSID_ConnectionCommonUi), // FAKE
  896. dwCharacteristics,
  897. reinterpret_cast<LPBYTE>("PersistData"), // FAKE
  898. celems("PersistData"), // FAKE
  899. L"Name", // FAKE
  900. L"DeviceName", // FAKE
  901. L"PhoneOrHostAddress"); // FAKE
  902. if (SUCCEEDED(hr))
  903. {
  904. DWORD dwIconId;
  905. BOOL fCanCache;
  906. hr = HrGetIconIDForPIDL(0, cfe, dwIconId, &fCanCache);
  907. if (SUCCEEDED(hr))
  908. {
  909. dwIconId &= ~MASK_CONNECTION; // Clear the current connection mask
  910. dwIconId |= (dwConnectionIcon << SHIFT_CONNECTION); // Set the new connection mask
  911. hr = HrGetIconFromIconId(dwIconSize, dwIconId, *phIcon);
  912. }
  913. }
  914. return hr;
  915. }
  916. //+---------------------------------------------------------------------------
  917. //
  918. // Function: CNetConfigIcons::HrUpdateSystemImageListForPIDL
  919. //
  920. // Purpose: Notifies the shell that we've changed an icon
  921. //
  922. // Arguments:
  923. // cfe [in] The connection folder entry that changed
  924. //
  925. // Returns:
  926. // HRESULT
  927. //
  928. // Author: deonb 18 Feb 2001
  929. //
  930. // Notes:
  931. //
  932. HRESULT CNetConfigIcons::HrUpdateSystemImageListForPIDL(IN const CConFoldEntry& cfe)
  933. {
  934. TraceFileFunc(ttidIcons);
  935. HRESULT hr = S_OK;
  936. DWORD dwIcon;
  937. BOOL fCacheThisIcon;
  938. hr = g_pNetConfigIcons->HrGetIconIDForPIDL(0, cfe, dwIcon, &fCacheThisIcon);
  939. if (SUCCEEDED(hr))
  940. {
  941. ULONG uFlags = GIL_PERINSTANCE | GIL_NOTFILENAME;
  942. if (!fCacheThisIcon)
  943. {
  944. uFlags |= GIL_DONTCACHE;
  945. }
  946. int iIcon = static_cast<int>(dwIcon);
  947. int iCachedImage = Shell_GetCachedImageIndex(c_szNetShellIcon, iIcon, uFlags);
  948. TraceTag(ttidIcons, "%S->SHUpdateImage [0x%08x] (iCachedImage=%d)", cfe.GetName(), dwIcon, iCachedImage);
  949. if (-1 != iCachedImage)
  950. {
  951. SHUpdateImage(c_szNetShellIcon, iIcon, uFlags, iCachedImage);
  952. }
  953. DWORD dwIconForShortcut;
  954. hr = g_pNetConfigIcons->HrGetIconIDForPIDL(GIL_FORSHORTCUT, cfe, dwIconForShortcut, &fCacheThisIcon);
  955. {
  956. if (dwIconForShortcut != dwIcon)
  957. {
  958. iIcon = static_cast<int>(dwIconForShortcut);
  959. iCachedImage = Shell_GetCachedImageIndex(c_szNetShellIcon, iIcon, uFlags);
  960. TraceTag(ttidIcons, "%S->SHUpdateImage GIL_FORSHORTCUT [0x%08x] (iCachedImage=%d)", cfe.GetName(), dwIcon, iCachedImage);
  961. if (-1 != iCachedImage)
  962. {
  963. SHUpdateImage(c_szNetShellIcon, iIcon, uFlags, iCachedImage);
  964. }
  965. }
  966. }
  967. }
  968. return hr;
  969. }