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.

2059 lines
69 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "connutil.h"
  4. #include "ncnetcon.h"
  5. #include "ncperms.h"
  6. #include "ncui.h"
  7. #include "lanui.h"
  8. #include "eapolui.h"
  9. #include "util.h"
  10. #include "lanhelp.h"
  11. #include "wzcprops.h"
  12. #include "eapolpage.h"
  13. #include "wzcpage.h"
  14. #include "wzcui.h"
  15. ////////////////////////////////////////////////////////////////////////
  16. // CWZCConfig related stuff
  17. //
  18. //+---------------------------------------------------------------------------
  19. // constructor
  20. CWZCConfig::CWZCConfig(DWORD dwFlags, PWZC_WLAN_CONFIG pwzcConfig)
  21. {
  22. m_dwFlags = dwFlags;
  23. CopyMemory(&m_wzcConfig, pwzcConfig, sizeof(WZC_WLAN_CONFIG));
  24. m_pPrev = m_pNext = this;
  25. m_nListIndex = -1;
  26. m_pEapolConfig = NULL;
  27. }
  28. //+---------------------------------------------------------------------------
  29. // destructor
  30. CWZCConfig::~CWZCConfig()
  31. {
  32. // remove the object from the list
  33. m_pPrev->m_pNext = m_pNext;
  34. m_pNext->m_pPrev = m_pPrev;
  35. if (m_pEapolConfig != NULL)
  36. {
  37. delete m_pEapolConfig;
  38. m_pEapolConfig = NULL;
  39. }
  40. }
  41. //+---------------------------------------------------------------------------
  42. // checks whether this configuration matches with the one from pwzcConfig
  43. BOOL
  44. CWZCConfig::Match(PWZC_WLAN_CONFIG pwzcConfig)
  45. {
  46. BOOL bMatch;
  47. // check whether the InfrastructureMode matches
  48. bMatch = (m_wzcConfig.InfrastructureMode == pwzcConfig->InfrastructureMode);
  49. // check whether the SSIDs are of the same length
  50. bMatch = bMatch && (m_wzcConfig.Ssid.SsidLength == pwzcConfig->Ssid.SsidLength);
  51. if (bMatch && m_wzcConfig.Ssid.SsidLength != 0)
  52. {
  53. // in case of Non empty SSIDs, check if they're the same
  54. bMatch = (memcmp(m_wzcConfig.Ssid.Ssid,
  55. pwzcConfig->Ssid.Ssid,
  56. m_wzcConfig.Ssid.SsidLength)) == 0;
  57. }
  58. return bMatch;
  59. }
  60. //+---------------------------------------------------------------------------
  61. // checks whether this configuration is weaker than the one given as parameter
  62. BOOL
  63. CWZCConfig::Weaker(PWZC_WLAN_CONFIG pwzcConfig)
  64. {
  65. BOOL bWeaker = FALSE;
  66. // a configuration is stronger if its privacy bit is set while the matching one is not set
  67. if (m_wzcConfig.Privacy != pwzcConfig->Privacy)
  68. bWeaker = pwzcConfig->Privacy;
  69. // if privacy bits are identical, a configuration is stronger if it has Open Auth mode
  70. else if (m_wzcConfig.AuthenticationMode != pwzcConfig->AuthenticationMode)
  71. bWeaker = (pwzcConfig->AuthenticationMode == Ndis802_11AuthModeOpen);
  72. return bWeaker;
  73. }
  74. DWORD
  75. CWZCConfig::AddConfigToListView(HWND hwndLV, INT nPos)
  76. {
  77. DWORD dwErr = ERROR_SUCCESS;
  78. // ugly but this is life. In order to convert the SSID to LPWSTR we need a buffer.
  79. // We know an SSID can't exceed 32 chars (see NDIS_802_11_SSID from ntddndis.h) so
  80. // make room for the null terminator and that's it. We could do mem alloc but I'm
  81. // not sure it worth the effort (at runtime).
  82. WCHAR wszSSID[33];
  83. UINT nLenSSID = 0;
  84. // convert the LPSTR (original SSID format) to LPWSTR (needed in List Ctrl)
  85. if (m_wzcConfig.Ssid.SsidLength != 0)
  86. {
  87. nLenSSID = MultiByteToWideChar(
  88. CP_ACP,
  89. 0,
  90. (LPCSTR)m_wzcConfig.Ssid.Ssid,
  91. m_wzcConfig.Ssid.SsidLength,
  92. wszSSID,
  93. celems(wszSSID));
  94. if (nLenSSID == 0)
  95. dwErr = GetLastError();
  96. }
  97. if (dwErr == ERROR_SUCCESS)
  98. {
  99. LVITEM lvi={0};
  100. UINT nImgIdx;
  101. // put the null terminator
  102. wszSSID[nLenSSID]=L'\0';
  103. // get the item's image index
  104. if (m_wzcConfig.InfrastructureMode == Ndis802_11Infrastructure)
  105. {
  106. nImgIdx = (m_dwFlags & WZC_DESCR_ACTIVE) ? WZCIMG_INFRA_ACTIVE :
  107. ((m_dwFlags & WZC_DESCR_VISIBLE) ? WZCIMG_INFRA_AIRING : WZCIMG_INFRA_SILENT);
  108. }
  109. else
  110. {
  111. nImgIdx = (m_dwFlags & WZC_DESCR_ACTIVE) ? WZCIMG_ADHOC_ACTIVE :
  112. ((m_dwFlags & WZC_DESCR_VISIBLE) ? WZCIMG_ADHOC_AIRING : WZCIMG_ADHOC_SILENT);
  113. }
  114. lvi.iItem = nPos;
  115. lvi.iSubItem = 0;
  116. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  117. lvi.pszText = wszSSID;
  118. lvi.iImage = nImgIdx;
  119. lvi.lParam = (LPARAM)this;
  120. // store the list position in the object
  121. m_nListIndex = ListView_InsertItem(hwndLV, &lvi);
  122. }
  123. return dwErr;
  124. }
  125. ////////////////////////////////////////////////////////////////////////
  126. // CWZeroConfPage related stuff
  127. //
  128. #define RFSH_TIMEOUT 3500
  129. UINT g_TimerID = 371;
  130. //+=================== PRIVATE MEMBERS =================================
  131. DWORD
  132. CWZeroConfPage::InitListViews()
  133. {
  134. RECT rc;
  135. LV_COLUMN lvc = {0};
  136. DWORD dwStyle;
  137. // initialize the image list styles
  138. dwStyle = ::GetWindowLong(m_hwndVLV, GWL_STYLE);
  139. ::SetWindowLong(m_hwndVLV, GWL_STYLE, (dwStyle | LVS_SHAREIMAGELISTS));
  140. dwStyle = ::GetWindowLong(m_hwndPLV, GWL_STYLE);
  141. ::SetWindowLong(m_hwndPLV, GWL_STYLE, (dwStyle | LVS_SHAREIMAGELISTS));
  142. // Create state image lists
  143. m_hImgs = ImageList_LoadBitmapAndMirror(
  144. _Module.GetResourceInstance(),
  145. MAKEINTRESOURCE(IDB_WZCSTATE),
  146. 16,
  147. 0,
  148. PALETTEINDEX(6));
  149. ListView_SetImageList(m_hwndVLV, m_hImgs, LVSIL_SMALL);
  150. ListView_SetImageList(m_hwndPLV, m_hImgs, LVSIL_SMALL);
  151. lvc.mask = LVCF_FMT | LVCF_WIDTH;
  152. lvc.fmt = LVCFMT_LEFT;
  153. ::GetClientRect(m_hwndVLV, &rc);
  154. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  155. //lvc.cx = rc.right;
  156. ListView_InsertColumn(m_hwndVLV, 0, &lvc);
  157. ::GetClientRect(m_hwndPLV, &rc);
  158. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  159. //lvc.cx = rc.right;
  160. ListView_InsertColumn(m_hwndPLV, 0, &lvc);
  161. ListView_SetExtendedListViewStyleEx(m_hwndPLV, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
  162. ListView_SetExtendedListViewStyleEx(m_hwndVLV, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
  163. return ERROR_SUCCESS;
  164. }
  165. //+=================== PUBLIC MEMBERS =================================
  166. //+---------------------------------------------------------------------
  167. // CWZeroConfPage constructor
  168. CWZeroConfPage::CWZeroConfPage(
  169. IUnknown* punk,
  170. INetCfg* pnc,
  171. INetConnection* pconn,
  172. const DWORD * adwHelpIDs)
  173. {
  174. m_pconn = pconn;
  175. m_pnc = pnc;
  176. m_adwHelpIDs = adwHelpIDs;
  177. // initialize the WZC data
  178. m_bHaveWZCData = FALSE;
  179. ZeroMemory(&m_IntfEntry, sizeof(INTF_ENTRY));
  180. m_dwOIDFlags = 0;
  181. m_nTimer = 0;
  182. m_hCursor = NULL;
  183. // initialize all the control's handles
  184. m_hckbEnable = NULL;
  185. m_hwndVLV = NULL;
  186. m_hwndPLV = NULL;
  187. m_hbtnCopy = NULL;
  188. m_hbtnRfsh = NULL;
  189. m_hbtnAdd = NULL;
  190. m_hbtnRem = NULL;
  191. m_hbtnUp = NULL;
  192. m_hbtnDown = NULL;
  193. m_hbtnAdvanced = NULL;
  194. m_hbtnProps = NULL;
  195. m_hlblVisNet = NULL;
  196. m_hlblPrefNet = NULL;
  197. m_hlblAvail = NULL;
  198. m_hlblPrefDesc = NULL;
  199. m_hlblAdvDesc = NULL;
  200. m_hbtnProps = NULL;
  201. m_hImgs = NULL;
  202. m_hIcoUp = NULL;
  203. m_hIcoDown = NULL;
  204. // default the infrastructure mode to Auto
  205. m_dwCtlFlags = (INTFCTL_ENABLED | INTFCTL_FALLBACK | Ndis802_11AutoUnknown);
  206. // init the internal list heads
  207. m_pHdVList = NULL;
  208. m_pHdPList = NULL;
  209. }
  210. //+---------------------------------------------------------------------
  211. CWZeroConfPage::~CWZeroConfPage()
  212. {
  213. if (m_hImgs != NULL)
  214. ImageList_Destroy(m_hImgs);
  215. if (m_hIcoUp != NULL)
  216. DeleteObject(m_hIcoUp);
  217. if (m_hIcoDown != NULL)
  218. DeleteObject(m_hIcoDown);
  219. // delete the internal INTF_ENTRY object
  220. WZCDeleteIntfObj(&m_IntfEntry);
  221. // delete the internal list of visible configurations
  222. // (is like filling it with NULL)
  223. FillVisibleList(NULL);
  224. // delete the internal list of preferred configurations
  225. // (is like filling it with NULL)
  226. FillPreferredList(NULL);
  227. if (m_nTimer != 0)
  228. KillTimer(m_nTimer);
  229. }
  230. //+---------------------------------------------------------------------
  231. // IsWireless - loads data from WZC if needed and checks whether the
  232. // interface is wireless or not.
  233. BOOL
  234. CWZeroConfPage::IsWireless()
  235. {
  236. if (!m_bHaveWZCData)
  237. {
  238. BOOL bOk;
  239. WCHAR wszGuid[c_cchGuidWithTerm];
  240. NETCON_PROPERTIES *pProps = NULL;
  241. bOk = SUCCEEDED(m_pconn->GetProperties(&pProps));
  242. if (bOk)
  243. {
  244. UINT cch;
  245. cch = ::StringFromGUID2(
  246. pProps->guidId,
  247. wszGuid,
  248. c_cchGuidWithTerm);
  249. FreeNetconProperties(pProps);
  250. bOk = (cch != 0);
  251. }
  252. if (bOk)
  253. {
  254. WZCDeleteIntfObj(&m_IntfEntry);
  255. ZeroMemory(&m_IntfEntry, sizeof(INTF_ENTRY));
  256. m_IntfEntry.wszGuid = (LPWSTR)RpcCAlloc(sizeof(WCHAR)*c_cchGuidWithTerm);
  257. bOk = (m_IntfEntry.wszGuid != NULL);
  258. }
  259. if (bOk)
  260. {
  261. DWORD dwErr;
  262. CopyMemory(m_IntfEntry.wszGuid, wszGuid, c_cchGuidWithTerm*sizeof(WCHAR));
  263. m_IntfEntry.wszDescr = NULL;
  264. m_dwOIDFlags = 0;
  265. dwErr = GetOIDs(INTF_ALL, &m_dwOIDFlags);
  266. // if getting the oids failed or we could get the OIDs but the driver/firmware
  267. // is not capable of doing the BSSID_LIST_SCAN it means we don't have enough
  268. // driver/firmware support for having Zero Configuration running. This will
  269. // result in not showing the Zero Configuration tab at all.
  270. bOk = (dwErr == ERROR_SUCCESS) && (m_IntfEntry.dwCtlFlags & INTFCTL_OIDSSUPP);
  271. if (m_IntfEntry.nAuthMode < 0)
  272. m_IntfEntry.nAuthMode = 0;
  273. if (m_IntfEntry.nInfraMode < 0)
  274. m_IntfEntry.nInfraMode = 0;
  275. if (!bOk)
  276. {
  277. WZCDeleteIntfObj(&m_IntfEntry);
  278. ZeroMemory(&m_IntfEntry, sizeof(INTF_ENTRY));
  279. }
  280. }
  281. m_bHaveWZCData = bOk;
  282. }
  283. return m_bHaveWZCData && (m_IntfEntry.ulPhysicalMediaType == NdisPhysicalMediumWirelessLan);
  284. }
  285. //+---------------------------------------------------------------------
  286. // GetOIDs - gets the OIDs for the m_IntfEntry member. It assumes the
  287. // GUID is set already
  288. DWORD
  289. CWZeroConfPage::GetOIDs(DWORD dwInFlags, LPDWORD pdwOutFlags)
  290. {
  291. DWORD rpcStatus, dwOutFlags;
  292. if (dwInFlags & INTF_DESCR)
  293. {
  294. RpcFree(m_IntfEntry.wszDescr);
  295. m_IntfEntry.wszDescr = NULL;
  296. }
  297. if (dwInFlags & INTF_PREFLIST)
  298. {
  299. RpcFree(m_IntfEntry.rdStSSIDList.pData);
  300. m_IntfEntry.rdStSSIDList.dwDataLen = 0;
  301. m_IntfEntry.rdStSSIDList.pData = NULL;
  302. }
  303. if (dwInFlags & INTF_SSID)
  304. {
  305. RpcFree(m_IntfEntry.rdSSID.pData);
  306. m_IntfEntry.rdSSID.dwDataLen = 0;
  307. m_IntfEntry.rdSSID.pData = NULL;
  308. }
  309. if (dwInFlags & INTF_BSSID)
  310. {
  311. RpcFree(m_IntfEntry.rdBSSID.pData);
  312. m_IntfEntry.rdBSSID.dwDataLen = 0;
  313. m_IntfEntry.rdBSSID.pData = NULL;
  314. }
  315. if (dwInFlags & INTF_BSSIDLIST)
  316. {
  317. RpcFree(m_IntfEntry.rdBSSIDList.pData);
  318. m_IntfEntry.rdBSSIDList.dwDataLen = 0;
  319. m_IntfEntry.rdBSSIDList.pData = NULL;
  320. }
  321. rpcStatus = WZCQueryInterface(
  322. NULL,
  323. dwInFlags,
  324. &m_IntfEntry,
  325. pdwOutFlags);
  326. return rpcStatus;
  327. }
  328. //+---------------------------------------------------------------------
  329. // HelpCenter - brings up the help topic given as parameter
  330. DWORD
  331. CWZeroConfPage::HelpCenter(LPCTSTR wszTopic)
  332. {
  333. DWORD dwErr = ERROR_SUCCESS;
  334. SHELLEXECUTEINFO shexinfo = {0};
  335. shexinfo.cbSize = sizeof (shexinfo);
  336. shexinfo.fMask = SEE_MASK_FLAG_NO_UI;
  337. shexinfo.nShow = SW_SHOWNORMAL;
  338. shexinfo.lpFile = wszTopic;
  339. shexinfo.lpVerb = _T("open");
  340. // since help center doesn't properly call AllowSetForegroundWindow when it defers
  341. // to an existing process we just give it to the next taker.
  342. AllowSetForegroundWindow(-1);
  343. ShellExecuteEx(&shexinfo);
  344. return dwErr;
  345. }
  346. //+---------------------------------------------------------------------
  347. // IsConfigInList - checks whether the pwzcConfig (WZC_WLAN_CONFIG object) is present
  348. // in the list given as the first param
  349. BOOL
  350. CWZeroConfPage::IsConfigInList(CWZCConfig *pHdList, PWZC_WLAN_CONFIG pwzcConfig, CWZCConfig **ppMatchingConfig)
  351. {
  352. BOOL bYes = FALSE;
  353. if (pHdList != NULL)
  354. {
  355. CWZCConfig *pConfig;
  356. pConfig = pHdList;
  357. do
  358. {
  359. if (pConfig->Match(pwzcConfig))
  360. {
  361. if (ppMatchingConfig != NULL)
  362. *ppMatchingConfig = pConfig;
  363. bYes = TRUE;
  364. break;
  365. }
  366. pConfig = pConfig->m_pNext;
  367. } while(pConfig != pHdList);
  368. }
  369. return bYes;
  370. }
  371. //+---------------------------------------------------------------------------
  372. // Adds the given configuration to the internal lists. The entries in the lists
  373. // are ordered on InfrastructureMode in descending order. This way the Infrastructure
  374. // entries will be on the top of the list while the adhoc entries will be on the
  375. // bottom. (we rely on the order as it is given in NDIS_802_11_NETWORK_INFRASTRUCTURE)
  376. DWORD
  377. CWZeroConfPage::AddUniqueConfig(
  378. DWORD dwOpFlags,
  379. DWORD dwEntryFlags,
  380. PWZC_WLAN_CONFIG pwzcConfig,
  381. CEapolConfig *pEapolConfig,
  382. CWZCConfig **ppNewNode)
  383. {
  384. LRESULT dwErr = ERROR_SUCCESS;
  385. CWZCConfig *pHdList;
  386. if (dwEntryFlags & WZC_DESCR_PREFRD)
  387. {
  388. pHdList = m_pHdPList;
  389. }
  390. else
  391. {
  392. UINT i;
  393. pHdList = m_pHdVList;
  394. // skip the null SSIDs from the visible list (coming from APs
  395. // not responding to broadcast SSID).
  396. for (i = pwzcConfig->Ssid.SsidLength; i > 0 && pwzcConfig->Ssid.Ssid[i-1] == 0; i--);
  397. if (i == 0)
  398. goto exit;
  399. }
  400. // if the list is currently empty, create the first entry as the head of the list
  401. if (pHdList == NULL)
  402. {
  403. pHdList = new CWZCConfig(dwEntryFlags, pwzcConfig);
  404. if (pHdList == NULL)
  405. {
  406. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  407. }
  408. else if (pEapolConfig == NULL)
  409. {
  410. pHdList->m_pEapolConfig = new CEapolConfig;
  411. if (pHdList->m_pEapolConfig == NULL)
  412. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  413. else
  414. dwErr = pHdList->m_pEapolConfig->LoadEapolConfig(m_IntfEntry.wszGuid, &(pHdList->m_wzcConfig.Ssid));
  415. if (dwErr != ERROR_SUCCESS)
  416. {
  417. delete pHdList;
  418. pHdList = NULL;
  419. }
  420. }
  421. else
  422. {
  423. pHdList->m_pEapolConfig = pEapolConfig;
  424. }
  425. // if the caller wants, return the pointer to the newly created object
  426. if (ppNewNode != NULL)
  427. *ppNewNode = pHdList;
  428. }
  429. else
  430. {
  431. // else the list already contains at least one element
  432. CWZCConfig *pCrt, *pHdGroup;
  433. // scan the list (keep in mind it is ordered descendingly on IM)
  434. pHdGroup = pCrt = pHdList;
  435. do
  436. {
  437. // check whether we entered a new group of configs (different InfrastructureMode)
  438. if (pHdGroup->m_wzcConfig.InfrastructureMode != pCrt->m_wzcConfig.InfrastructureMode)
  439. pHdGroup = pCrt;
  440. // if found an identical entry (same SSID and same InfraMode)
  441. // signal the DUPLICATE_TAG error
  442. if (pCrt->Match(pwzcConfig))
  443. {
  444. // merge the flags first
  445. pCrt->m_dwFlags |= dwEntryFlags;
  446. // If requested, copy over the new configuration.
  447. // If not explicitly requested, copy over only if the existent configuration
  448. // prooves to be weaker than the one being added.
  449. //
  450. // NOTE: the pCrt->m_pEapolConfig remains untouched since it depends exclusively
  451. // on the SSID & Infrastructure mode. These are not changing hence there is no
  452. // reason to reload the 802.1x settings.
  453. if (dwOpFlags & WZCADD_OVERWRITE ||
  454. (pHdList == m_pHdVList && pCrt->Weaker(pwzcConfig)))
  455. {
  456. memcpy(&(pCrt->m_wzcConfig), pwzcConfig, sizeof(WZC_WLAN_CONFIG));
  457. // just in case a different pEapolConfig has been provided, destroy
  458. // the original one (if any) and point to the new object
  459. if (pEapolConfig != NULL)
  460. {
  461. if (pCrt->m_pEapolConfig != NULL)
  462. delete pCrt->m_pEapolConfig;
  463. pCrt->m_pEapolConfig = pEapolConfig;
  464. }
  465. }
  466. // if the caller wants, return the pointer to the matching entry
  467. if (ppNewNode != NULL)
  468. *ppNewNode = pCrt;
  469. // signal there is already a matching config
  470. dwErr = ERROR_DUPLICATE_TAG;
  471. }
  472. pCrt = pCrt->m_pNext;
  473. } while (dwErr == ERROR_SUCCESS &&
  474. pCrt != pHdList &&
  475. pwzcConfig->InfrastructureMode <= pCrt->m_wzcConfig.InfrastructureMode);
  476. // if dwErr is unchanged, this means a new node has to be added ahead of pCrt node
  477. if (dwErr == ERROR_SUCCESS)
  478. {
  479. // create the new config and insert it ahead of this node.
  480. CWZCConfig *pNewConfig;
  481. pNewConfig = new CWZCConfig(dwEntryFlags, pwzcConfig);
  482. if (pNewConfig == NULL)
  483. {
  484. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  485. }
  486. else if (pEapolConfig == NULL)
  487. {
  488. pNewConfig->m_pEapolConfig = new CEapolConfig;
  489. if (pNewConfig->m_pEapolConfig == NULL)
  490. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  491. else
  492. dwErr = pNewConfig->m_pEapolConfig->LoadEapolConfig(m_IntfEntry.wszGuid, &(pNewConfig->m_wzcConfig.Ssid));
  493. if (dwErr != ERROR_SUCCESS)
  494. {
  495. delete pNewConfig;
  496. pNewConfig = NULL;
  497. }
  498. }
  499. else
  500. {
  501. pNewConfig->m_pEapolConfig = pEapolConfig;
  502. }
  503. if (dwErr == ERROR_SUCCESS)
  504. {
  505. INT nDiff;
  506. // if asked to insert in the head of the group, pCrt should point to this head
  507. if (dwOpFlags & WZCADD_HIGROUP)
  508. pCrt = pHdGroup;
  509. pNewConfig->m_pPrev = pCrt->m_pPrev;
  510. pNewConfig->m_pNext = pCrt;
  511. pCrt->m_pPrev->m_pNext = pNewConfig;
  512. pCrt->m_pPrev = pNewConfig;
  513. // get the difference between the Infrastructure modes for the new node and
  514. // for the current head
  515. nDiff = pNewConfig->m_wzcConfig.InfrastructureMode - pHdList->m_wzcConfig.InfrastructureMode;
  516. // if the newly entered entry has the largest "key" in
  517. // the existent sequence, or it has to be inserted in the head of its group and it is
  518. // in the first group, then the global list head moves to the new entry
  519. if (nDiff > 0 || ((dwOpFlags & WZCADD_HIGROUP) && (nDiff == 0)))
  520. pHdList = pNewConfig;
  521. }
  522. // if the caller wants, return the pointer to the newly created object
  523. if (ppNewNode != NULL)
  524. *ppNewNode = pNewConfig;
  525. }
  526. }
  527. if (dwEntryFlags & WZC_DESCR_PREFRD)
  528. {
  529. m_pHdPList = pHdList;
  530. }
  531. else
  532. {
  533. m_pHdVList = pHdList;
  534. }
  535. exit:
  536. return (DWORD)dwErr;
  537. }
  538. //+---------------------------------------------------------------------
  539. // FillVisibleList - fills in the configs from the WZC_802_11_CONFIG_LIST object
  540. // into the list of visible configs
  541. DWORD
  542. CWZeroConfPage::FillVisibleList(PWZC_802_11_CONFIG_LIST pwzcVList)
  543. {
  544. DWORD dwErr = ERROR_SUCCESS;
  545. UINT i;
  546. // cleanup whatever we might already have in the visible list
  547. if (m_pHdVList != NULL)
  548. {
  549. while (m_pHdVList->m_pNext != m_pHdVList)
  550. {
  551. delete m_pHdVList->m_pNext;
  552. }
  553. delete m_pHdVList;
  554. m_pHdVList = NULL;
  555. }
  556. if (pwzcVList != NULL)
  557. {
  558. for (i = 0; i < pwzcVList->NumberOfItems; i++)
  559. {
  560. dwErr = AddUniqueConfig(
  561. 0, // no op flags
  562. WZC_DESCR_VISIBLE, // this is a visible entry
  563. &(pwzcVList->Config[i]));
  564. // reset the error if config was just duplicated
  565. if (dwErr == ERROR_DUPLICATE_TAG)
  566. dwErr = ERROR_SUCCESS;
  567. }
  568. }
  569. return dwErr;
  570. }
  571. //+---------------------------------------------------------------------
  572. // FillPreferredList - fills in the configs from the WZC_802_11_CONFIG_LIST object
  573. // into the list of preferred configs
  574. DWORD
  575. CWZeroConfPage::FillPreferredList(PWZC_802_11_CONFIG_LIST pwzcPList)
  576. {
  577. DWORD dwErr = ERROR_SUCCESS;
  578. UINT i;
  579. // cleanup whatever we might already have in the preferred list
  580. if (m_pHdPList != NULL)
  581. {
  582. while (m_pHdPList ->m_pNext != m_pHdPList)
  583. {
  584. delete m_pHdPList ->m_pNext;
  585. }
  586. delete m_pHdPList;
  587. m_pHdPList = NULL;
  588. }
  589. if (pwzcPList != NULL)
  590. {
  591. for (i = 0; i < pwzcPList->NumberOfItems; i++)
  592. {
  593. PWZC_WLAN_CONFIG pwzcPConfig = &(pwzcPList->Config[i]);
  594. DWORD dwFlags = WZC_DESCR_PREFRD;
  595. // check whether this preferred is also visible and adjust dwFlags if so
  596. if (IsConfigInList(m_pHdVList, pwzcPConfig))
  597. dwFlags |= WZC_DESCR_VISIBLE;
  598. dwErr = AddUniqueConfig(
  599. WZCADD_OVERWRITE, // preferred entries cause info to be overwritten
  600. dwFlags,
  601. pwzcPConfig);
  602. // reset the error if config was just duplicated
  603. if (dwErr == ERROR_DUPLICATE_TAG)
  604. dwErr = ERROR_SUCCESS;
  605. }
  606. }
  607. return dwErr;
  608. }
  609. //+---------------------------------------------------------------------------
  610. // Fill in the current configuration settings for this adapter
  611. DWORD
  612. CWZeroConfPage::FillCurrentConfig(PINTF_ENTRY pIntf)
  613. {
  614. DWORD dwErr = ERROR_SUCCESS;
  615. WZC_WLAN_CONFIG wzcCurrent = {0};
  616. CWZCConfig *pConfig = NULL;
  617. wzcCurrent.InfrastructureMode = (NDIS_802_11_NETWORK_INFRASTRUCTURE)pIntf->nInfraMode;
  618. wzcCurrent.Ssid.SsidLength = pIntf->rdSSID.dwDataLen;
  619. CopyMemory(wzcCurrent.Ssid.Ssid, pIntf->rdSSID.pData, pIntf->rdSSID.dwDataLen);
  620. // another bit of a hack. Code in the authentication mode for this adapter in the highest
  621. // of the two reserved bits from WZC_WLAN_CONFIG
  622. //NWB_SET_AUTHMODE(&wzcCurrent, pIntf->nAuthMode);
  623. wzcCurrent.AuthenticationMode = (NDIS_802_11_AUTHENTICATION_MODE)pIntf->nAuthMode;
  624. // set the privacy field based on the adapter's WEP status.
  625. wzcCurrent.Privacy = (pIntf->nWepStatus == Ndis802_11WEPEnabled);
  626. if (IsConfigInList(m_pHdVList, &wzcCurrent, &pConfig))
  627. pConfig->m_dwFlags |= WZC_DESCR_ACTIVE;
  628. if (IsConfigInList(m_pHdPList, &wzcCurrent, &pConfig))
  629. pConfig->m_dwFlags |= WZC_DESCR_ACTIVE;
  630. return dwErr;
  631. }
  632. //+---------------------------------------------------------------------------
  633. // Display the Visible & Preferred lists into their controls
  634. DWORD
  635. CWZeroConfPage::RefreshListView(DWORD dwFlags)
  636. {
  637. DWORD dwErr = ERROR_SUCCESS;
  638. CWZCConfig *pActive = NULL;
  639. while (dwFlags != 0)
  640. {
  641. HWND hwndLV;
  642. CWZCConfig *pHdList;
  643. // the logic below allows iteration through all the lists
  644. // requested by the caller
  645. if (dwFlags & WZCOP_VLIST)
  646. {
  647. dwFlags ^= WZCOP_VLIST;
  648. hwndLV = m_hwndVLV;
  649. pHdList = m_pHdVList;
  650. }
  651. else if (dwFlags & WZCOP_PLIST)
  652. {
  653. dwFlags ^= WZCOP_PLIST;
  654. hwndLV = m_hwndPLV;
  655. pHdList = m_pHdPList;
  656. }
  657. else
  658. break;
  659. // clear first the list
  660. ListView_DeleteAllItems(hwndLV);
  661. if (pHdList != NULL)
  662. {
  663. CWZCConfig *pCrt;
  664. UINT i;
  665. pCrt = pHdList;
  666. i = 0;
  667. do
  668. {
  669. // add in the list all the entries if AutoMode or we're filling the
  670. // visible list.
  671. // Otherwise (!AutoMode & Preferred list) put in just the entries for
  672. // the corresponding infrastructure mode
  673. if ((m_dwCtlFlags & INTFCTL_CM_MASK) == Ndis802_11AutoUnknown ||
  674. hwndLV == m_hwndVLV ||
  675. (m_dwCtlFlags & INTFCTL_CM_MASK) == pCrt->m_wzcConfig.InfrastructureMode)
  676. {
  677. pCrt->m_nListIndex = i;
  678. pCrt->AddConfigToListView(hwndLV, i++);
  679. if (pCrt->m_dwFlags & WZC_DESCR_ACTIVE)
  680. pActive = pCrt;
  681. }
  682. else
  683. {
  684. pCrt->m_nListIndex = -1;
  685. }
  686. pCrt = pCrt->m_pNext;
  687. } while (pCrt != pHdList);
  688. if (pActive != NULL)
  689. {
  690. ListView_SetItemState(hwndLV, pActive->m_nListIndex, LVIS_SELECTED, LVIS_SELECTED);
  691. ListView_EnsureVisible(hwndLV, pActive->m_nListIndex, FALSE);
  692. }
  693. else if (i > 0)
  694. {
  695. ListView_SetItemState(hwndLV, 0, LVIS_SELECTED, LVIS_SELECTED);
  696. ListView_EnsureVisible(hwndLV, 0, FALSE);
  697. }
  698. }
  699. }
  700. return dwErr;
  701. }
  702. DWORD
  703. CWZeroConfPage::RefreshButtons()
  704. {
  705. CWZCConfig *pVConfig = NULL;
  706. CWZCConfig *pPConfig = NULL;
  707. LVITEM lvi = {0};
  708. INT iSelected;
  709. BOOL bEnabled;
  710. // get the selected item from the visible list
  711. iSelected = ListView_GetNextItem(m_hwndVLV, -1, LVNI_SELECTED);
  712. if (iSelected >= 0)
  713. {
  714. lvi.mask = LVIF_PARAM;
  715. lvi.iItem = iSelected;
  716. if (ListView_GetItem(m_hwndVLV, &lvi))
  717. {
  718. pVConfig = (CWZCConfig*)lvi.lParam;
  719. }
  720. }
  721. // get the selected item from the preferred list
  722. iSelected = ListView_GetNextItem(m_hwndPLV, -1, LVNI_SELECTED);
  723. if (iSelected >= 0)
  724. {
  725. lvi.mask = LVIF_PARAM;
  726. lvi.iItem = iSelected;
  727. if (ListView_GetItem(m_hwndPLV, &lvi))
  728. {
  729. pPConfig = (CWZCConfig*)lvi.lParam;
  730. }
  731. }
  732. // enable buttons only if not during refresh - otherwise disable all
  733. bEnabled = (m_dwOIDFlags & INTF_BSSIDLIST);
  734. // "Refresh" button is enabled if we do have the visible list
  735. // "Refresh" button might be enabled even if the service is disabled. User can see what is visible
  736. ::EnableWindow(m_hbtnRfsh, bEnabled);
  737. bEnabled = bEnabled && (m_dwCtlFlags & INTFCTL_ENABLED);
  738. // "Copy" button is enabled if there is any selection in the Visible list
  739. ::EnableWindow(m_hbtnCopy, bEnabled && (pVConfig != NULL) &&
  740. ((m_dwCtlFlags & INTFCTL_CM_MASK) == Ndis802_11AutoUnknown ||
  741. (m_dwCtlFlags & INTFCTL_CM_MASK) == pVConfig->m_wzcConfig.InfrastructureMode));
  742. // "Add" Button is always enabled, regardless the selections
  743. ::EnableWindow(m_hbtnAdd, bEnabled);
  744. // "Remove" button is active only if there is any selection in the Preferred list
  745. ::EnableWindow(m_hbtnRem, bEnabled && (pPConfig != NULL));
  746. // Same test for "properties" button as for "remove"
  747. ::EnableWindow(m_hbtnProps, bEnabled && (pPConfig != NULL));
  748. // "Up" button is active only for preferred entries.
  749. // It also is active only if the entry is not the first in the
  750. // list and the entry preceding it has the same InfrastructureMode
  751. bEnabled = bEnabled && (pPConfig != NULL);
  752. bEnabled = bEnabled && (pPConfig != m_pHdPList);
  753. bEnabled = bEnabled &&
  754. (pPConfig->m_wzcConfig.InfrastructureMode == pPConfig->m_pPrev->m_wzcConfig.InfrastructureMode);
  755. ::EnableWindow(m_hbtnUp, bEnabled);
  756. // "Down" button is active only for preferred or preferred entries.
  757. // It also is active only if the entry is not the last in the list
  758. // and it precedes another entry of exactly the same InfrastructureMode
  759. bEnabled = (m_dwCtlFlags & INTFCTL_ENABLED) && (m_dwOIDFlags & INTF_BSSIDLIST);
  760. bEnabled = bEnabled && (pPConfig != NULL);
  761. bEnabled = bEnabled && (pPConfig->m_pNext != m_pHdPList);
  762. bEnabled = bEnabled &&
  763. (pPConfig->m_wzcConfig.InfrastructureMode == pPConfig->m_pNext->m_wzcConfig.InfrastructureMode);
  764. ::EnableWindow(m_hbtnDown, bEnabled);
  765. return ERROR_SUCCESS;
  766. }
  767. //+---------------------------------------------------------------------
  768. DWORD
  769. CWZeroConfPage::SwapConfigsInListView(INT nIdx1, INT nIdx2, CWZCConfig * & pConfig1, CWZCConfig * & pConfig2)
  770. {
  771. DWORD dwErr = ERROR_SUCCESS;
  772. LVITEM lvi1 = {0};
  773. LVITEM lvi2 = {0};
  774. WCHAR wszSSID1[33];
  775. WCHAR wszSSID2[33];
  776. // since we take all what is known about an item this includes
  777. // images indices and selection state
  778. // get the first item
  779. lvi1.iItem = nIdx1;
  780. lvi1.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE | LVIF_PARAM;
  781. lvi1.stateMask = (UINT)-1;
  782. lvi1.pszText = wszSSID1;
  783. lvi1.cchTextMax = sizeof(wszSSID1)/sizeof(WCHAR);
  784. if (!ListView_GetItem(m_hwndPLV, &lvi1))
  785. {
  786. dwErr = ERROR_GEN_FAILURE;
  787. goto exit;
  788. }
  789. pConfig1 = (CWZCConfig*)lvi1.lParam;
  790. // get the second item
  791. lvi2.iItem = nIdx2;
  792. lvi2.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE | LVIF_PARAM;
  793. lvi2.stateMask = (UINT)-1;
  794. lvi2.pszText = wszSSID2;
  795. lvi2.cchTextMax = sizeof(wszSSID2)/sizeof(WCHAR);
  796. if (!ListView_GetItem(m_hwndPLV, &lvi2))
  797. {
  798. dwErr = ERROR_GEN_FAILURE;
  799. goto exit;
  800. }
  801. pConfig2 = (CWZCConfig*)lvi2.lParam;
  802. // swap the indices and reset the items at their new positions
  803. lvi1.iItem = nIdx2;
  804. lvi2.iItem = nIdx1;
  805. if (!ListView_SetItem(m_hwndPLV, &lvi1) ||
  806. !ListView_SetItem(m_hwndPLV, &lvi2))
  807. {
  808. dwErr = ERROR_GEN_FAILURE;
  809. goto exit;
  810. }
  811. // if everything went fine, swap the indices in the objects
  812. pConfig1->m_nListIndex = nIdx2;
  813. pConfig2->m_nListIndex = nIdx1;
  814. // make visible the selected entry
  815. ListView_EnsureVisible(m_hwndPLV, nIdx1, FALSE);
  816. exit:
  817. return dwErr;
  818. }
  819. //+---------------------------------------------------------------------
  820. DWORD
  821. CWZeroConfPage::SavePreferredConfigs(PINTF_ENTRY pIntf)
  822. {
  823. DWORD dwErr = ERROR_SUCCESS;
  824. CWZCConfig *pCrt = NULL;
  825. UINT nPrefrd = 0;
  826. if (m_pHdPList != NULL)
  827. {
  828. // count first the number of preferred entries in the list
  829. pCrt = m_pHdPList;
  830. do
  831. {
  832. nPrefrd++;
  833. pCrt = pCrt->m_pNext;
  834. } while(pCrt != m_pHdPList);
  835. }
  836. if (nPrefrd > 0)
  837. {
  838. PWZC_802_11_CONFIG_LIST pwzcPrefrdList;
  839. UINT nwzcPrefrdSize;
  840. nwzcPrefrdSize = sizeof(WZC_802_11_CONFIG_LIST)+ (nPrefrd-1)*sizeof(WZC_WLAN_CONFIG);
  841. // allocate as much memory as needed for storing all the preferred SSIDs
  842. pwzcPrefrdList = (PWZC_802_11_CONFIG_LIST)RpcCAlloc(nwzcPrefrdSize);
  843. if (pwzcPrefrdList == NULL)
  844. {
  845. dwErr = GetLastError();
  846. }
  847. else
  848. {
  849. LRESULT dwLErr;
  850. pwzcPrefrdList->NumberOfItems = 0;
  851. // we have now all we need - start copying the preferred
  852. pCrt = m_pHdPList;
  853. do
  854. {
  855. PWZC_WLAN_CONFIG pPrefrdConfig;
  856. pPrefrdConfig = &(pwzcPrefrdList->Config[pwzcPrefrdList->NumberOfItems++]);
  857. CopyMemory(pPrefrdConfig, &pCrt->m_wzcConfig, sizeof(WZC_WLAN_CONFIG));
  858. // fix 802.1X state for infrastructure networks only.
  859. // don't touch the 802.1X state for ad hoc networks since this might mess the setting for a
  860. // corresponding Infrastructure network (802.1X engine doesn't make the difference between SSID infra
  861. // and SSID ad hoc) and besides, the 802.1X engine is smart enough to not act on ad hoc networks
  862. if (pCrt->m_pEapolConfig != NULL &&
  863. pPrefrdConfig->InfrastructureMode == Ndis802_11Infrastructure)
  864. {
  865. dwLErr = pCrt->m_pEapolConfig->SaveEapolConfig(m_IntfEntry.wszGuid, &(pCrt->m_wzcConfig.Ssid));
  866. if (dwErr == ERROR_SUCCESS)
  867. dwErr = (DWORD)dwLErr;
  868. }
  869. pCrt = pCrt->m_pNext;
  870. } while(pwzcPrefrdList->NumberOfItems < nPrefrd && pCrt != m_pHdPList);
  871. // since we don't want any "one time configuration" logic to apply here,
  872. // we need to put in the whole number of items in the "Index" field
  873. pwzcPrefrdList->Index = pwzcPrefrdList->NumberOfItems;
  874. pIntf->rdStSSIDList.dwDataLen = nwzcPrefrdSize;
  875. pIntf->rdStSSIDList.pData = (LPBYTE)pwzcPrefrdList;
  876. }
  877. }
  878. else
  879. {
  880. pIntf->rdStSSIDList.dwDataLen = 0;
  881. pIntf->rdStSSIDList.pData = NULL;
  882. }
  883. return dwErr;
  884. }
  885. //+---------------------------------------------------------------------
  886. LRESULT CWZeroConfPage::OnInitDialog(
  887. UINT uMsg,
  888. WPARAM wParam,
  889. LPARAM lParam,
  890. BOOL& bHandled)
  891. {
  892. HRESULT hr = S_OK;
  893. BOOL bEnableAll;
  894. BOOL bEnableVisible;
  895. // get the controls as the first thing to do
  896. m_hckbEnable = GetDlgItem(IDC_WZC_CHK_EnableWZC);
  897. m_hlblVisNet = GetDlgItem(IDC_WZC_LBL_VisNet);
  898. m_hlblPrefNet = GetDlgItem(IDC_WZC_LBL_PrefNet);
  899. m_hlblAvail = GetDlgItem(IDC_AVAILLABEL);
  900. m_hlblPrefDesc = GetDlgItem(IDC_PREFERLABEL);
  901. m_hlblAdvDesc = GetDlgItem(IDC_ADVANCEDLABEL);
  902. m_hwndVLV = GetDlgItem(IDC_WZC_LVW_BSSIDList);
  903. m_hwndPLV = GetDlgItem(IDC_WZC_LVW_StSSIDList);
  904. m_hbtnUp = GetDlgItem(IDC_WZC_BTN_UP);
  905. m_hbtnDown = GetDlgItem(IDC_WZC_BTN_DOWN);
  906. m_hbtnCopy = GetDlgItem(IDC_WZC_BTN_COPY);
  907. m_hbtnRfsh = GetDlgItem(IDC_WZC_BTN_RFSH);
  908. m_hbtnAdd = GetDlgItem(IDC_WZC_BTN_ADD);
  909. m_hbtnRem = GetDlgItem(IDC_WZC_BTN_REM);
  910. m_hbtnAdvanced = GetDlgItem(IDC_ADVANCED);
  911. m_hbtnProps = GetDlgItem(IDC_PROPERTIES);
  912. // Initialize the list view controls
  913. InitListViews();
  914. // enable UI only for Admins and if the interface is wireless
  915. // As a side effect, IsWireless() loads the data from the WZC
  916. bEnableAll = /*FIsUserAdmin() &&*/ IsWireless();
  917. bEnableVisible = bEnableAll;
  918. if (bEnableAll)
  919. {
  920. // set the configuration mode to the one for this interface
  921. m_dwCtlFlags = m_IntfEntry.dwCtlFlags;
  922. // if service disabled, gray out everything
  923. bEnableAll = (m_dwCtlFlags & INTFCTL_ENABLED);
  924. // set the control check boxes
  925. CheckDlgButton(IDC_WZC_CHK_EnableWZC,
  926. (m_dwCtlFlags & INTFCTL_ENABLED) ? BST_CHECKED : BST_UNCHECKED);
  927. // the UI can be filled in only when we were able to retrieve the list of
  928. // visible configs (even if it is NULL/empty). Otherwise, the UI is locked.
  929. if (m_dwOIDFlags & INTF_BSSIDLIST)
  930. {
  931. // add the list of visible configs for this adapter
  932. FillVisibleList((PWZC_802_11_CONFIG_LIST)m_IntfEntry.rdBSSIDList.pData);
  933. // add the list of preferred configs for this adapter
  934. FillPreferredList((PWZC_802_11_CONFIG_LIST)m_IntfEntry.rdStSSIDList.pData);
  935. // add to the visible list the current settings
  936. FillCurrentConfig(&m_IntfEntry);
  937. // dump the resulting lists in their List Views
  938. RefreshListView(WZCOP_VLIST|WZCOP_PLIST);
  939. // if we got a visible list, have to enable it here
  940. bEnableVisible = TRUE;
  941. }
  942. else
  943. {
  944. // mark that we don't have WZC data yet
  945. m_bHaveWZCData = FALSE;
  946. // the list of preferred configs still needs to be filled up here
  947. FillPreferredList((PWZC_802_11_CONFIG_LIST)m_IntfEntry.rdStSSIDList.pData);
  948. // switch the cursor to "App starting"
  949. m_hCursor = SetCursor(LoadCursor(NULL, IDC_APPSTARTING));
  950. // we should fill in the UI after Tr (see the WZC state machine)
  951. // Tr is 3secs (defined in ..zeroconf\server\state.h)
  952. m_nTimer = SetTimer(g_TimerID, RFSH_TIMEOUT, 0);
  953. // don't enable any control if refreshing
  954. bEnableAll = FALSE;
  955. // actually disable even the "Enable" button
  956. ::EnableWindow(m_hckbEnable, FALSE);
  957. // and also disable the visible list
  958. bEnableVisible = FALSE;
  959. }
  960. // refresh the buttons
  961. RefreshButtons();
  962. }
  963. // the controls related to the visible list should be enabled if:
  964. // - WZC can operate on this adapter
  965. // - we got a BSSIDLIST from the very first shot.
  966. // otherwise these controls should remain disabled
  967. ::EnableWindow(m_hlblVisNet, bEnableVisible);
  968. ::EnableWindow(m_hwndVLV, bEnableVisible);
  969. ::EnableWindow(m_hlblAvail, bEnableVisible);
  970. // all the remaining controls should be enabled only if:
  971. // - WZC can operate on the adapter
  972. // - WZC is enabled as a service
  973. // - we got the BSSIDLIST from the very first shot
  974. // otherwise these controls should remain disabled
  975. ::EnableWindow(m_hlblPrefNet, bEnableAll);
  976. ::EnableWindow(m_hwndPLV, bEnableAll);
  977. ::EnableWindow(m_hlblPrefDesc, bEnableAll);
  978. ::EnableWindow(m_hlblAdvDesc, bEnableAll);
  979. ::EnableWindow(m_hbtnAdvanced, bEnableAll);
  980. return LresFromHr(hr);
  981. }
  982. //+---------------------------------------------------------------------
  983. LRESULT CWZeroConfPage::OnApply(
  984. int idCtrl,
  985. LPNMHDR pnmh,
  986. BOOL& bHandled)
  987. {
  988. HRESULT hr = S_OK;
  989. WCHAR wszGuid[c_cchGuidWithTerm];
  990. NETCON_PROPERTIES *pProps = NULL;
  991. DWORD rpcStatus = ERROR_SUCCESS;
  992. BOOL bOk;
  993. hr = m_pconn->GetProperties(&pProps);
  994. bOk = SUCCEEDED(hr);
  995. if (bOk)
  996. {
  997. UINT cch;
  998. cch = ::StringFromGUID2(
  999. pProps->guidId,
  1000. wszGuid,
  1001. c_cchGuidWithTerm);
  1002. FreeNetconProperties(pProps);
  1003. bOk = (cch != 0);
  1004. }
  1005. if (bOk)
  1006. {
  1007. UINT nText;
  1008. INTF_ENTRY Intf;
  1009. BOOL bDirty;
  1010. DWORD dwOneXErr;
  1011. ZeroMemory(&Intf, sizeof(INTF_ENTRY));
  1012. Intf.wszGuid = wszGuid;
  1013. // copy the configuration mode
  1014. Intf.dwCtlFlags = m_dwCtlFlags;
  1015. // save the preferred config list
  1016. dwOneXErr = SavePreferredConfigs(&Intf);
  1017. bDirty = (Intf.dwCtlFlags != m_IntfEntry.dwCtlFlags);
  1018. bDirty = bDirty || (Intf.rdStSSIDList.dwDataLen != m_IntfEntry.rdStSSIDList.dwDataLen);
  1019. bDirty = bDirty || ((Intf.rdStSSIDList.dwDataLen != 0) &&
  1020. memcmp(Intf.rdStSSIDList.pData, m_IntfEntry.rdStSSIDList.pData, Intf.rdStSSIDList.dwDataLen));
  1021. if (bDirty)
  1022. {
  1023. rpcStatus = WZCSetInterface(
  1024. NULL,
  1025. INTF_ALL_FLAGS | INTF_PREFLIST,
  1026. &Intf,
  1027. NULL);
  1028. }
  1029. if (dwOneXErr != ERROR_SUCCESS || rpcStatus == ERROR_PARTIAL_COPY)
  1030. {
  1031. NcMsgBox(
  1032. _Module.GetResourceInstance(),
  1033. m_hWnd,
  1034. IDS_LANUI_ERROR_CAPTION,
  1035. IDS_WZC_PARTIAL_APPLY,
  1036. MB_ICONEXCLAMATION|MB_OK);
  1037. rpcStatus = RPC_S_OK;
  1038. }
  1039. bOk = (rpcStatus == RPC_S_OK);
  1040. // wszGuid field is not pointing to heap memory hence it should not
  1041. // be deleted -> set the pointer to NULL to avoid this to happen
  1042. Intf.wszGuid = NULL;
  1043. WZCDeleteIntfObj(&Intf);
  1044. }
  1045. return LresFromHr(hr);
  1046. }
  1047. //+---------------------------------------------------------------------
  1048. extern const WCHAR c_szNetCfgHelpFile[];
  1049. LRESULT
  1050. CWZeroConfPage::OnContextMenu(
  1051. UINT uMsg,
  1052. WPARAM wParam,
  1053. LPARAM lParam,
  1054. BOOL& fHandled)
  1055. {
  1056. if (m_adwHelpIDs != NULL)
  1057. {
  1058. ::WinHelp(m_hWnd,
  1059. c_szNetCfgHelpFile,
  1060. HELP_CONTEXTMENU,
  1061. (ULONG_PTR)m_adwHelpIDs);
  1062. }
  1063. return 0;
  1064. }
  1065. LRESULT
  1066. CWZeroConfPage::OnHelp(
  1067. UINT uMsg,
  1068. WPARAM wParam,
  1069. LPARAM lParam,
  1070. BOOL& fHandled)
  1071. {
  1072. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  1073. if ((m_adwHelpIDs != NULL) && (HELPINFO_WINDOW == lphi->iContextType))
  1074. {
  1075. ::WinHelp(static_cast<HWND>(lphi->hItemHandle),
  1076. c_szNetCfgHelpFile,
  1077. HELP_WM_HELP,
  1078. (ULONG_PTR)m_adwHelpIDs);
  1079. }
  1080. return 0;
  1081. }
  1082. //+---------------------------------------------------------------------
  1083. LRESULT
  1084. CWZeroConfPage::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1085. {
  1086. if (m_nTimer != 0)
  1087. {
  1088. BOOL bEnableAll;
  1089. // switch the cursor back to whatever it was
  1090. SetCursor(LoadCursor(NULL, IDC_ARROW));
  1091. KillTimer(m_nTimer);
  1092. m_nTimer = 0;
  1093. // attempt to requery the service for all the OIDs. Regardless we could or not
  1094. // obtain the OIDs, fill the UI with what we have.
  1095. if (GetOIDs(INTF_ALL_OIDS, &m_dwOIDFlags) == ERROR_SUCCESS)
  1096. {
  1097. CWZCConfig *pPConfig = NULL;
  1098. // add the list of visible configs for this adapter
  1099. FillVisibleList((PWZC_802_11_CONFIG_LIST)m_IntfEntry.rdBSSIDList.pData);
  1100. // Update the visibility flag for each of the preferred configs
  1101. pPConfig = m_pHdPList;
  1102. if (pPConfig != NULL)
  1103. {
  1104. do
  1105. {
  1106. // by default, none of the preferred entries is marked as "active".
  1107. // This will be taken care of later, when calling FillCurrentConfig().
  1108. pPConfig->m_dwFlags &= ~WZC_DESCR_ACTIVE;
  1109. if (IsConfigInList(m_pHdVList, &pPConfig->m_wzcConfig))
  1110. pPConfig->m_dwFlags |= WZC_DESCR_VISIBLE;
  1111. else
  1112. pPConfig->m_dwFlags &= ~WZC_DESCR_VISIBLE;
  1113. pPConfig = pPConfig->m_pNext;
  1114. } while(pPConfig != m_pHdPList);
  1115. }
  1116. // add the current settings to the visible list
  1117. FillCurrentConfig(&m_IntfEntry);
  1118. }
  1119. // even in case of failure, at this point we should live with whatever
  1120. // visible list (if any) we have. Hence, flag BSSIDLIST as "visible"
  1121. m_dwOIDFlags |= INTF_BSSIDLIST;
  1122. // dump the resulting lists in their List Views
  1123. RefreshListView(WZCOP_VLIST|WZCOP_PLIST);
  1124. // refresh the buttons
  1125. RefreshButtons();
  1126. // if service disabled, gray out all the other controls
  1127. bEnableAll = (m_dwCtlFlags & INTFCTL_ENABLED);
  1128. // enable all the UI when done refreshing
  1129. ::EnableWindow(m_hckbEnable, TRUE);
  1130. // enable everything related to the visible list
  1131. ::EnableWindow(m_hlblVisNet, TRUE);
  1132. ::EnableWindow(m_hwndVLV, TRUE);
  1133. ::EnableWindow(m_hlblAvail, TRUE);
  1134. ::EnableWindow(m_hlblPrefNet, bEnableAll);
  1135. ::EnableWindow(m_hwndPLV, bEnableAll);
  1136. ::EnableWindow(m_hlblPrefDesc, bEnableAll);
  1137. ::EnableWindow(m_hlblAdvDesc, bEnableAll);
  1138. ::EnableWindow(m_hbtnAdvanced, bEnableAll);
  1139. }
  1140. return 0;
  1141. }
  1142. //+---------------------------------------------------------------------
  1143. LRESULT CWZeroConfPage::OnDblClick(
  1144. int idCtrl,
  1145. LPNMHDR pnmh,
  1146. BOOL& bHandled)
  1147. {
  1148. HWND hwndLV;
  1149. HRESULT hr = S_OK;
  1150. LPNMLISTVIEW pnmhLv = (LPNMLISTVIEW) pnmh;
  1151. if (idCtrl == IDC_WZC_LVW_BSSIDList)
  1152. {
  1153. hwndLV = m_hwndVLV;
  1154. }
  1155. else
  1156. {
  1157. hwndLV = m_hwndPLV;
  1158. }
  1159. bHandled = FALSE;
  1160. if (pnmhLv->iItem != -1)
  1161. {
  1162. ListView_SetItemState(hwndLV, pnmhLv->iItem, LVIS_SELECTED, LVIS_SELECTED);
  1163. hr = _DoProperties(hwndLV, pnmhLv->iItem);
  1164. bHandled = TRUE;
  1165. }
  1166. return LresFromHr(hr);
  1167. }
  1168. //+---------------------------------------------------------------------
  1169. LRESULT CWZeroConfPage::OnClick(
  1170. int idCtrl,
  1171. LPNMHDR pnmh,
  1172. BOOL& bHandled)
  1173. {
  1174. HRESULT hr = S_OK;
  1175. LPNMLISTVIEW pnmhLv = (LPNMLISTVIEW) pnmh;
  1176. if (idCtrl == IDC_LEARNABOUT)
  1177. {
  1178. HelpCenter(SzLoadString(_Module.GetResourceInstance(), IDS_WZC_LEARNCMD));
  1179. }
  1180. return LresFromHr(hr);
  1181. }
  1182. //+---------------------------------------------------------------------
  1183. LRESULT CWZeroConfPage::OnReturn(
  1184. int idCtrl,
  1185. LPNMHDR pnmh,
  1186. BOOL& bHandled)
  1187. {
  1188. HRESULT hr = S_OK;
  1189. LPNMLISTVIEW pnmhLv = (LPNMLISTVIEW) pnmh;
  1190. if (idCtrl == IDC_LEARNABOUT)
  1191. {
  1192. HelpCenter(SzLoadString(_Module.GetResourceInstance(), IDS_WZC_LEARNCMD));
  1193. }
  1194. return LresFromHr(hr);
  1195. }
  1196. //+---------------------------------------------------------------------
  1197. LRESULT CWZeroConfPage::OnItemChanged(
  1198. int idCtrl,
  1199. LPNMHDR pnmh,
  1200. BOOL& bHandled)
  1201. {
  1202. HRESULT hr = S_OK;
  1203. RefreshButtons();
  1204. bHandled = TRUE;
  1205. return LresFromHr(hr);
  1206. }
  1207. //+---------------------------------------------------------------------
  1208. LRESULT CWZeroConfPage::OnChkWZCEnable(
  1209. WORD wNotifyCode,
  1210. WORD wID,
  1211. HWND hWndCtl,
  1212. BOOL& bHandled)
  1213. {
  1214. HRESULT hr = S_OK;
  1215. BOOL bEnable;
  1216. bEnable = (IsDlgButtonChecked(IDC_WZC_CHK_EnableWZC) == BST_CHECKED);
  1217. m_dwCtlFlags &= ~INTFCTL_ENABLED;
  1218. if (bEnable)
  1219. m_dwCtlFlags |= INTFCTL_ENABLED;
  1220. // enable everything related to the visible list
  1221. ::EnableWindow(m_hlblVisNet, TRUE);
  1222. ::EnableWindow(m_hwndVLV, TRUE);
  1223. ::EnableWindow(m_hlblAvail, TRUE);
  1224. ::EnableWindow(m_hlblPrefNet, bEnable);
  1225. ::EnableWindow(m_hwndPLV, bEnable);
  1226. ::EnableWindow(m_hlblPrefDesc, bEnable);
  1227. ::EnableWindow(m_hlblAdvDesc, bEnable);
  1228. ::EnableWindow(m_hbtnAdvanced, bEnable);
  1229. RefreshButtons();
  1230. return LresFromHr(hr);
  1231. }
  1232. //+---------------------------------------------------------------------
  1233. LRESULT
  1234. CWZeroConfPage::OnPushAddOrCopy(
  1235. WORD wNotifyCode,
  1236. WORD wID,
  1237. HWND hWndCtl,
  1238. BOOL& bHandled)
  1239. {
  1240. HRESULT hr = S_OK;
  1241. LVITEM lvi = {0};
  1242. BOOL bOk;
  1243. INT iSelected;
  1244. CWZCConfig *pConfig = NULL;
  1245. CWZCConfigPage PpWzcProps(WZCDLG_PROPS_RWALL|WZCDLG_PROPS_DEFOK|WZCDLG_PROPS_ONEX_CHECK);
  1246. CEapolConfig *pEapolConfig = NULL;
  1247. // in case of success, the object allocated here is linked to the
  1248. // newly created or updated CWZCConfig and will be deleted when
  1249. // this latter one gets destroyed.
  1250. pEapolConfig = new CEapolConfig;
  1251. bOk = (pEapolConfig != NULL);
  1252. if (bOk)
  1253. {
  1254. if (hWndCtl == m_hbtnCopy)
  1255. {
  1256. // get the selected item from the Visible list
  1257. iSelected = ListView_GetNextItem(m_hwndVLV, -1, LVNI_SELECTED);
  1258. bOk = (iSelected != -1);
  1259. // there is a valid selection to copy (it couldn't be otherwise since
  1260. // "Copy" shouldn't be enabled if there is no such selection)
  1261. // Find the CWZCConfig for the selection
  1262. if (bOk)
  1263. {
  1264. LVITEM lvi = {0};
  1265. lvi.mask = LVIF_PARAM;
  1266. lvi.iItem = iSelected;
  1267. if (ListView_GetItem(m_hwndVLV, &lvi))
  1268. {
  1269. pConfig = (CWZCConfig*)lvi.lParam;
  1270. if (pConfig != NULL)
  1271. {
  1272. UINT nVisPrivacy = pConfig->m_wzcConfig.Privacy;
  1273. // check whether this config is in the preferred list. If IsConfigInList
  1274. // succeeds, it returns in pConfig the pointer to the preferred config - this is
  1275. // what we need to show the properties for.
  1276. // If this network is not in the preferred list, pConfig will not be modified hence
  1277. // the properties coming from the AP will be loaded. Again what we want.
  1278. IsConfigInList(m_pHdPList, &pConfig->m_wzcConfig, &pConfig);
  1279. // copy in the newly created 802.1x object what we have for this configuration
  1280. pEapolConfig->CopyEapolConfig(pConfig->m_pEapolConfig);
  1281. // upload the 802.11 settings into the property page
  1282. PpWzcProps.UploadWzcConfig(pConfig);
  1283. // However, even if we're showing up preferred, settings, the Privacy bit from the AP
  1284. // (the visible configuration) takes precedence.
  1285. if (nVisPrivacy)
  1286. {
  1287. PpWzcProps.m_wzcConfig.Privacy = nVisPrivacy;
  1288. }
  1289. }
  1290. }
  1291. bOk = (pConfig != NULL);
  1292. }
  1293. }
  1294. else
  1295. {
  1296. // this is a brand new network, we don't know even the SSID,
  1297. // let 802.1x start with its defaults then.
  1298. pEapolConfig->LoadEapolConfig(m_IntfEntry.wszGuid, NULL);
  1299. bOk = TRUE;
  1300. }
  1301. }
  1302. // we have the CWZCConfig object, prompt the user with it allowing
  1303. // him to change whatever params he want
  1304. if (bOk)
  1305. {
  1306. CWLANAuthenticationPage PpAuthProps(NULL, m_pnc, m_pconn, g_aHelpIDs_IDD_SECURITY);
  1307. // if the mode is not "auto", freeze it in the dialog
  1308. if ((m_dwCtlFlags & INTFCTL_CM_MASK) != Ndis802_11AutoUnknown)
  1309. {
  1310. PpWzcProps.m_wzcConfig.InfrastructureMode = (NDIS_802_11_NETWORK_INFRASTRUCTURE)(m_dwCtlFlags & INTFCTL_CM_MASK);
  1311. PpWzcProps.SetFlags(WZCDLG_PROPS_RWINFR, 0);
  1312. }
  1313. PpAuthProps.UploadEapolConfig(pEapolConfig, &PpWzcProps);
  1314. PpWzcProps.UploadEapolConfig(pEapolConfig);
  1315. bOk = (_DoModalPropSheet(&PpWzcProps, &PpAuthProps) > 0);
  1316. }
  1317. // the dialog was ack-ed, the dialog contains the WZC_WLAN_CONFIG to be added
  1318. // go ahead and create the list entry for it.
  1319. if (bOk)
  1320. {
  1321. DWORD dwFlags = WZC_DESCR_PREFRD;
  1322. DWORD dwErr;
  1323. // it could happen that the newly added config is visible
  1324. if (IsConfigInList(m_pHdVList, &PpWzcProps.m_wzcConfig))
  1325. dwFlags |= WZC_DESCR_VISIBLE;
  1326. // we have now a WZC_WLAN_CONFIG structure in the dialog
  1327. // we have to add it to the list view and to the internal list as
  1328. // a preferred one. This call doesn't fix the list index
  1329. // and doesn't insert the new config in the ListView.
  1330. dwErr = AddUniqueConfig(
  1331. WZCADD_OVERWRITE | WZCADD_HIGROUP,
  1332. dwFlags,
  1333. &PpWzcProps.m_wzcConfig,
  1334. pEapolConfig, // 802.1x settings need to be updated no matter what
  1335. &pConfig);
  1336. // if the addition returns success, it means this is a brand new
  1337. // entry! Then fix the indices and add the entry to the list view
  1338. if (dwErr == ERROR_SUCCESS)
  1339. {
  1340. CWZCConfig *pCrt = pConfig;
  1341. INT nCrtIdx = 0;
  1342. // if everything went up fine, we need to fix the indices and
  1343. // create/add the list view item
  1344. // find the first index above the newly entry item.
  1345. // pConfig already has the m_nListIndex set to -1;
  1346. if (pConfig == m_pHdPList)
  1347. {
  1348. nCrtIdx = 0;
  1349. }
  1350. else
  1351. {
  1352. do
  1353. {
  1354. pCrt = pCrt->m_pPrev;
  1355. if (pCrt->m_nListIndex != -1)
  1356. {
  1357. nCrtIdx = pCrt->m_nListIndex+1;
  1358. break;
  1359. }
  1360. } while(pCrt != m_pHdPList);
  1361. }
  1362. pConfig->m_nListIndex = nCrtIdx++;
  1363. pCrt = pConfig->m_pNext;
  1364. while(pCrt != m_pHdPList)
  1365. {
  1366. if (pCrt->m_nListIndex != -1)
  1367. pCrt->m_nListIndex = nCrtIdx++;
  1368. pCrt = pCrt->m_pNext;
  1369. }
  1370. pConfig->AddConfigToListView(m_hwndPLV, pConfig->m_nListIndex);
  1371. }
  1372. bOk = (dwErr == ERROR_SUCCESS) || (dwErr == ERROR_DUPLICATE_TAG);
  1373. }
  1374. if (bOk)
  1375. {
  1376. ListView_SetItemState(m_hwndPLV, pConfig->m_nListIndex, LVIS_SELECTED, LVIS_SELECTED);
  1377. ListView_EnsureVisible(m_hwndPLV, pConfig->m_nListIndex, FALSE);
  1378. RefreshButtons();
  1379. }
  1380. if (!bOk && pEapolConfig != NULL)
  1381. delete pEapolConfig;
  1382. bHandled = bOk;
  1383. return LresFromHr(hr);
  1384. }
  1385. //+---------------------------------------------------------------------
  1386. LRESULT
  1387. CWZeroConfPage::OnPushRefresh(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1388. {
  1389. HRESULT hr = S_OK;
  1390. DWORD rpcStatus;
  1391. DWORD dwOutFlags;
  1392. // since we are here, it means we have already got the info for this adapter, hence
  1393. // we already have its GUID in the m_IntfEntry member.
  1394. // All we have to do is to ask WZCSVC for a visible list rescan
  1395. rpcStatus = WZCRefreshInterface(
  1396. NULL,
  1397. INTF_LIST_SCAN,
  1398. &m_IntfEntry,
  1399. &dwOutFlags);
  1400. // if everything went fine, just disable the "Refresh" button and set
  1401. // the timer for the future query
  1402. if (rpcStatus == RPC_S_OK &&
  1403. dwOutFlags & INTF_LIST_SCAN)
  1404. {
  1405. ::EnableWindow(m_hbtnRfsh, FALSE);
  1406. // mark that we don't have WZC data yet
  1407. m_bHaveWZCData = FALSE;
  1408. // switch the cursor to the "app starting"
  1409. m_hCursor = SetCursor(LoadCursor(NULL, IDC_APPSTARTING));
  1410. m_nTimer = SetTimer(g_TimerID, RFSH_TIMEOUT, 0);
  1411. // indicate we don't have the visible list in order
  1412. // to disable all the buttons
  1413. m_dwOIDFlags &= ~INTF_BSSIDLIST;
  1414. RefreshButtons();
  1415. // disable all the UI while refreshing
  1416. ::EnableWindow(m_hckbEnable, FALSE);
  1417. ::EnableWindow(m_hwndVLV, FALSE);
  1418. ::EnableWindow(m_hwndPLV, FALSE);
  1419. ::EnableWindow(m_hlblVisNet, FALSE);
  1420. ::EnableWindow(m_hlblPrefNet, FALSE);
  1421. ::EnableWindow(m_hlblAvail, FALSE);
  1422. ::EnableWindow(m_hlblPrefDesc, FALSE);
  1423. ::EnableWindow(m_hlblAdvDesc, FALSE);
  1424. ::EnableWindow(m_hbtnAdvanced, FALSE);
  1425. }
  1426. return LresFromHr(hr);
  1427. }
  1428. //+---------------------------------------------------------------------
  1429. LRESULT
  1430. CWZeroConfPage::OnPushUpOrDown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1431. {
  1432. HRESULT hr = S_OK;
  1433. INT iSelected;
  1434. INT iOther;
  1435. CWZCConfig *pConfig, *pOther;
  1436. // no matter what, get the selected item from the list
  1437. iSelected = ListView_GetNextItem(m_hwndPLV, -1, LVNI_SELECTED);
  1438. // since we are here it means there is another entry up/down side
  1439. // with which the selected one needs to change place
  1440. // first delete the entry from its current position in the list
  1441. iOther = (hWndCtl == m_hbtnDown)? iSelected+1 : iSelected-1;
  1442. // swap first the visual elements (entries in the List View)
  1443. // This returns the CWZCConfig pointers with their indices already
  1444. // adjusted
  1445. if (SwapConfigsInListView(iSelected, iOther, pConfig, pOther) == ERROR_SUCCESS)
  1446. {
  1447. // if need to go down one hop..
  1448. if (hWndCtl == m_hbtnDown)
  1449. {
  1450. // swap positions in the list
  1451. // remove the entry from its current position
  1452. pOther->m_pPrev = pConfig->m_pPrev;
  1453. pConfig->m_pPrev->m_pNext = pOther;
  1454. // and put it back down to its successor
  1455. pConfig->m_pPrev = pOther;
  1456. pConfig->m_pNext = pOther->m_pNext;
  1457. pOther->m_pNext->m_pPrev = pConfig;
  1458. pOther->m_pNext = pConfig;
  1459. // fix the m_pHdPList if needed;
  1460. if (m_pHdPList == pConfig)
  1461. m_pHdPList = pOther;
  1462. }
  1463. // if need to go up one hop..
  1464. else
  1465. {
  1466. // swap positions in the list
  1467. // remove the entry from its current position
  1468. pOther->m_pNext = pConfig->m_pNext;
  1469. pConfig->m_pNext->m_pPrev = pOther;
  1470. // and put it back in front of its predecessor
  1471. pConfig->m_pNext = pOther;
  1472. pConfig->m_pPrev = pOther->m_pPrev;
  1473. pOther->m_pPrev->m_pNext = pConfig;
  1474. pOther->m_pPrev = pConfig;
  1475. // fix the m_pHdPList if needed
  1476. if (m_pHdPList == pOther)
  1477. m_pHdPList = pConfig;
  1478. }
  1479. }
  1480. // need to refresh the buttons such that the "Up"/"Down" buttons
  1481. // get updated for the new position of the selection
  1482. RefreshButtons();
  1483. bHandled = TRUE;
  1484. return LresFromHr(hr);
  1485. }
  1486. //+---------------------------------------------------------------------
  1487. LRESULT CWZeroConfPage::OnPushRemove(
  1488. WORD wNotifyCode,
  1489. WORD wID,
  1490. HWND hWndCtl,
  1491. BOOL& bHandled)
  1492. {
  1493. HRESULT hr = S_OK;
  1494. LVITEM lvi = {0};
  1495. CWZCConfig *pConfig, *pCrt;
  1496. INT iSelected;
  1497. iSelected = ListView_GetNextItem(m_hwndPLV, -1, LVNI_SELECTED);
  1498. lvi.mask = LVIF_PARAM;
  1499. lvi.iItem = iSelected;
  1500. if (!ListView_GetItem(m_hwndPLV, &lvi))
  1501. goto exit;
  1502. // get the CWZCConfig from it
  1503. pConfig = (CWZCConfig*)lvi.lParam;
  1504. // adjust the list indices for all the entries that follow
  1505. // the selected one
  1506. for (pCrt = pConfig->m_pNext; pCrt != m_pHdPList; pCrt = pCrt->m_pNext)
  1507. {
  1508. if (pCrt->m_nListIndex != -1)
  1509. pCrt->m_nListIndex--;
  1510. }
  1511. // determine first which entry gets the selection
  1512. // the selection moves down if there is any other entry down, or up otherwise
  1513. pCrt = (pConfig->m_pNext == m_pHdPList) ? pConfig->m_pPrev : pConfig->m_pNext;
  1514. // if after that the selection still points to the same object, it means
  1515. // it is the only one in the list so the head and selection are set to NULL
  1516. if (pCrt == pConfig)
  1517. {
  1518. m_pHdPList = pCrt = NULL;
  1519. }
  1520. // otherwise, if it is the head of the list which gets removed, the head
  1521. // moves down to the next entry
  1522. else if (m_pHdPList == pConfig)
  1523. {
  1524. m_pHdPList = pConfig->m_pNext;
  1525. }
  1526. // delete now the selected entry from the list
  1527. ListView_DeleteItem(m_hwndPLV, iSelected);
  1528. // and destroy its object (desctructor takes care of list removal)
  1529. delete pConfig;
  1530. // set the new selection if any
  1531. if (pCrt != NULL)
  1532. {
  1533. ListView_SetItemState(m_hwndPLV, pCrt->m_nListIndex, LVIS_SELECTED, LVIS_SELECTED);
  1534. ListView_EnsureVisible(m_hwndPLV, pCrt->m_nListIndex, FALSE);
  1535. }
  1536. // refresh the buttons' state
  1537. RefreshButtons();
  1538. bHandled = TRUE;
  1539. exit:
  1540. return LresFromHr(hr);
  1541. }
  1542. LRESULT CWZeroConfPage::OnPushAdvanced(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1543. {
  1544. bHandled = TRUE;
  1545. DialogBoxParam(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDD_LAN_WZC_ADVANCED), m_hWnd, AdvancedDialogProc, (LPARAM) this);
  1546. RefreshListView(WZCOP_VLIST|WZCOP_PLIST);
  1547. RefreshButtons();
  1548. return 0;
  1549. }
  1550. LRESULT CWZeroConfPage::OnPushProperties(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1551. {
  1552. bHandled = TRUE;
  1553. int iItem = ListView_GetNextItem(m_hwndPLV, -1, LVNI_SELECTED);
  1554. if (-1 != iItem)
  1555. {
  1556. _DoProperties(m_hwndPLV, iItem);
  1557. }
  1558. return 0;
  1559. }
  1560. HRESULT CWZeroConfPage::_DoProperties(HWND hwndLV, int iItem)
  1561. {
  1562. LV_ITEM lvi = {0};
  1563. // we need to get to the corresponding config object
  1564. lvi.mask = LVIF_PARAM;
  1565. lvi.iItem = iItem;
  1566. if (ListView_GetItem(hwndLV, &lvi) && lvi.lParam != NULL)
  1567. {
  1568. CWZCConfig *pConfig = (CWZCConfig*)lvi.lParam;
  1569. if (hwndLV == m_hwndVLV)
  1570. {
  1571. CWZCConfigProps dlgProps;
  1572. dlgProps.UploadWzcConfig(pConfig);
  1573. // bring up the info dialog (it only has "Close" so the user can't
  1574. // change anything there, hence there is no reason to do anything
  1575. // more here.
  1576. dlgProps.DoModal(m_hWnd);
  1577. }
  1578. else
  1579. {
  1580. BOOL bOk = FALSE;
  1581. CWZCConfigPage PpWzcProps(WZCDLG_PROPS_RWAUTH|WZCDLG_PROPS_RWWEP);
  1582. CEapolConfig *pEapolConfig;
  1583. PpWzcProps.UploadWzcConfig(pConfig);
  1584. pEapolConfig = new CEapolConfig;
  1585. bOk = (pEapolConfig != NULL);
  1586. if (bOk)
  1587. {
  1588. CWLANAuthenticationPage PpAuthProps(NULL, m_pnc, m_pconn, g_aHelpIDs_IDD_SECURITY);
  1589. pEapolConfig->CopyEapolConfig(pConfig->m_pEapolConfig);
  1590. PpAuthProps.UploadEapolConfig(pEapolConfig, &PpWzcProps);
  1591. PpWzcProps.UploadEapolConfig(pEapolConfig);
  1592. bOk = (_DoModalPropSheet(&PpWzcProps, &PpAuthProps, TRUE) > 0);
  1593. }
  1594. // bring up the modal property sheet
  1595. if (bOk)
  1596. {
  1597. // copy over the info from the dialog. SSID & Infra Mode should have been locked
  1598. // so the position of this entry in the internal and UI list has not changed
  1599. memcpy(&pConfig->m_wzcConfig, &PpWzcProps.m_wzcConfig, sizeof(WZC_WLAN_CONFIG));
  1600. delete pConfig->m_pEapolConfig;
  1601. pConfig->m_pEapolConfig = pEapolConfig;
  1602. }
  1603. if (!bOk && pEapolConfig != NULL)
  1604. delete pEapolConfig;
  1605. }
  1606. }
  1607. return S_OK;
  1608. }
  1609. INT CWZeroConfPage::_DoModalPropSheet(CWZCConfigPage *pPpWzcPage, CWLANAuthenticationPage *pPpAuthPage, BOOL bCustomizeTitle)
  1610. {
  1611. INT retCode = 0;
  1612. PROPSHEETHEADER psh;
  1613. HPROPSHEETPAGE hpsp[2];
  1614. INT npsp = 0;
  1615. LPWSTR pwszCaption = NULL;
  1616. hpsp[0] = pPpWzcPage->CreatePage(IDC_WZC_DLG_PROPS, 0); npsp++;
  1617. if (hpsp[0] == NULL)
  1618. return -1;
  1619. if(pPpAuthPage != NULL)
  1620. {
  1621. hpsp[1] = pPpAuthPage->CreatePage(IDD_LAN_SECURITY, 0); npsp++;
  1622. if (hpsp[1] == NULL)
  1623. return -1;
  1624. }
  1625. ZeroMemory (&psh, sizeof(psh));
  1626. psh.dwSize = sizeof( PROPSHEETHEADER );
  1627. psh.dwFlags = PSH_NOAPPLYNOW ;
  1628. psh.hwndParent = m_hWnd;
  1629. psh.hInstance = _Module.GetResourceInstance();
  1630. psh.nPages = npsp;
  1631. psh.phpage = hpsp;
  1632. psh.nStartPage = 0;
  1633. // just double check the SsidLength is no larger than the allowed size!
  1634. if (bCustomizeTitle && pPpWzcPage->m_wzcConfig.Ssid.SsidLength <= 32)
  1635. {
  1636. WCHAR wszSSID[33];
  1637. LPVOID pvArgs[1];
  1638. if (pPpWzcPage->m_wzcConfig.Ssid.SsidLength)
  1639. {
  1640. UINT nLen = 0;
  1641. nLen = MultiByteToWideChar(
  1642. CP_ACP,
  1643. 0,
  1644. (LPCSTR)pPpWzcPage->m_wzcConfig.Ssid.Ssid,
  1645. pPpWzcPage->m_wzcConfig.Ssid.SsidLength,
  1646. wszSSID,
  1647. celems(wszSSID)-1); // no more than 32 WCHARs reserved for the SSID
  1648. wszSSID[nLen] = L'\0';
  1649. }
  1650. pvArgs[0] = &(wszSSID[0]);
  1651. // don't care of the return value - if the function fails, psh.pszCaption is set to NULL which
  1652. // is handled further down.
  1653. FormatMessage(
  1654. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1655. SzLoadString(_Module.GetResourceInstance(), IDS_WZC_DLG_CAP_SUFFIX),
  1656. 0,
  1657. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1658. (LPTSTR) &pwszCaption,
  1659. 0,
  1660. (va_list*)pvArgs);
  1661. psh.pszCaption = pwszCaption;
  1662. }
  1663. if (psh.pszCaption == NULL)
  1664. {
  1665. psh.pszCaption = SzLoadString(_Module.GetResourceInstance(), IDS_WZC_DLG_CAPTION);
  1666. }
  1667. retCode = (INT)PropertySheet(&psh);
  1668. if (pwszCaption != NULL)
  1669. LocalFree(pwszCaption);
  1670. return retCode;
  1671. }
  1672. // Advanced dialog
  1673. INT_PTR CALLBACK CWZeroConfPage::AdvancedDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1674. {
  1675. // Get the pointer to our instance from where we stashed it.
  1676. CWZeroConfPage* pThis = (CWZeroConfPage*) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
  1677. if (!pThis)
  1678. {
  1679. if (WM_INITDIALOG == uMsg)
  1680. {
  1681. // Stash our instance pointer
  1682. pThis = (CWZeroConfPage*) lParam;
  1683. ::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pThis);
  1684. }
  1685. }
  1686. if (pThis)
  1687. {
  1688. switch (uMsg)
  1689. {
  1690. case WM_INITDIALOG:
  1691. {
  1692. // select the correct item by default
  1693. NDIS_802_11_NETWORK_INFRASTRUCTURE mode = (NDIS_802_11_NETWORK_INFRASTRUCTURE)(pThis->m_dwCtlFlags & INTFCTL_CM_MASK);
  1694. UINT idSelect;
  1695. switch (mode)
  1696. {
  1697. case Ndis802_11IBSS:
  1698. // Computer-to-computer
  1699. idSelect = IDC_ADHOC;
  1700. break;
  1701. case Ndis802_11Infrastructure:
  1702. // infrastructure (access point) network
  1703. idSelect = IDC_INFRA;
  1704. break;
  1705. case Ndis802_11AutoUnknown:
  1706. default:
  1707. // Any network (access point preferred)
  1708. idSelect = IDC_ANYNET;
  1709. };
  1710. // Select the right radio button
  1711. ::SendDlgItemMessage(hwnd, idSelect, BM_SETCHECK, BST_CHECKED, 0);
  1712. // Check the "fallback to visible networks" checkbox if necessary
  1713. ::SendDlgItemMessage(hwnd, IDC_WZC_CHK_Fallback, BM_SETCHECK, (pThis->m_dwCtlFlags & INTFCTL_FALLBACK) ? BST_CHECKED : BST_UNCHECKED, 0);
  1714. }
  1715. return TRUE;
  1716. case WM_COMMAND:
  1717. switch(LOWORD(wParam))
  1718. {
  1719. case IDOK:
  1720. {
  1721. // ...Set the connectivity mode...
  1722. NDIS_802_11_NETWORK_INFRASTRUCTURE mode = Ndis802_11AutoUnknown;
  1723. // See what type of network connectivity the user selected
  1724. if (BST_CHECKED == ::SendDlgItemMessage(hwnd, IDC_ADHOC, BM_GETCHECK, 0, 0))
  1725. {
  1726. // Computer-to-computer
  1727. mode = Ndis802_11IBSS;
  1728. }
  1729. else if (BST_CHECKED == ::SendDlgItemMessage(hwnd, IDC_INFRA, BM_GETCHECK, 0, 0))
  1730. {
  1731. // infrastructure (access point) network
  1732. mode = Ndis802_11Infrastructure;
  1733. }
  1734. else if (BST_CHECKED == ::SendDlgItemMessage(hwnd, IDC_ANYNET, BM_GETCHECK, 0, 0))
  1735. {
  1736. // Any network (access point preferred)
  1737. mode = Ndis802_11AutoUnknown;
  1738. }
  1739. pThis->m_dwCtlFlags &= ~INTFCTL_CM_MASK;
  1740. pThis->m_dwCtlFlags |= (((DWORD) mode) & INTFCTL_CM_MASK);
  1741. // Set the "fallback to visible networks" flag
  1742. pThis->m_dwCtlFlags &= ~INTFCTL_FALLBACK;
  1743. if (BST_CHECKED == ::SendDlgItemMessage(hwnd, IDC_WZC_CHK_Fallback, BM_GETCHECK, 0, 0))
  1744. {
  1745. pThis->m_dwCtlFlags |= INTFCTL_FALLBACK;
  1746. }
  1747. ::EndDialog(hwnd, IDOK);
  1748. }
  1749. return TRUE;
  1750. }
  1751. break;
  1752. case WM_CLOSE:
  1753. ::EndDialog(hwnd, IDCANCEL);
  1754. return TRUE;
  1755. case WM_CONTEXTMENU:
  1756. {
  1757. ::WinHelp(hwnd,
  1758. c_szNetCfgHelpFile,
  1759. HELP_CONTEXTMENU,
  1760. (ULONG_PTR)g_aHelpIDs_IDC_WZC_ADVANCED);
  1761. return TRUE;
  1762. }
  1763. case WM_HELP:
  1764. {
  1765. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  1766. ::WinHelp(static_cast<HWND>(lphi->hItemHandle),
  1767. c_szNetCfgHelpFile,
  1768. HELP_WM_HELP,
  1769. (ULONG_PTR)g_aHelpIDs_IDC_WZC_ADVANCED);
  1770. return TRUE;
  1771. }
  1772. }
  1773. }
  1774. return FALSE;
  1775. }