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.

527 lines
15 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "ncnetcon.h"
  4. #include "conprops.h"
  5. #include "commconn.h" // Standard shell\commconn includes
  6. #include "commconp.h" // Private shell\commconn includes
  7. #include "resource.h"
  8. #include "ncperms.h"
  9. typedef struct
  10. {
  11. NETCON_MEDIATYPE nct;
  12. NETCON_CHOOSETYPE ncct;
  13. UINT nIDI;
  14. INT nIDI_Idx;
  15. } ConnTypeChooserMap;
  16. static ConnTypeChooserMap ConnTypeMap[] = {
  17. {NCM_DIRECT, NCCHT_DIRECT_CONNECT, IDI_DB_GEN_S_16, 0},
  18. {NCM_LAN, NCCHT_LAN, IDI_LB_GEN_S_16, 0},
  19. {NCM_PHONE, NCCHT_PHONE, IDI_PB_GEN_S_16, 0},
  20. {NCM_ISDN, NCCHT_ISDN, IDI_PB_GEN_S_16, 0},
  21. {NCM_TUNNEL, NCCHT_TUNNEL, IDI_TB_GEN_S_16, 0}};
  22. CChooseConnectionData::CChooseConnectionData(INetConnection * pConn)
  23. {
  24. Assert(pConn);
  25. m_pConn = pConn;
  26. AddRefObj(m_pConn);
  27. m_Nct = NCM_LAN;
  28. m_Ncs = NCS_DISCONNECTED;
  29. m_dwChar = 0;
  30. }
  31. HRESULT CChooseConnectionData::HrCreate(INetConnection * pNetCon,
  32. CChooseConnectionData **ppData)
  33. {
  34. HRESULT hr = E_OUTOFMEMORY;
  35. CChooseConnectionData * pData = NULL;
  36. NETCON_PROPERTIES * pProps = NULL;
  37. pData = new CChooseConnectionData(pNetCon);
  38. if (NULL == pData)
  39. goto Error;
  40. hr = pNetCon->GetProperties(&pProps);
  41. if (FAILED(hr))
  42. goto Error;
  43. Assert(NULL != pProps->pszwName);
  44. pData->SetName(pProps->pszwName);
  45. pData->SetCharacteristics(pProps->dwCharacter);
  46. pData->SetType(pProps->MediaType);
  47. pData->SetStatus(pProps->Status);
  48. Error:
  49. if (FAILED(hr))
  50. {
  51. delete pData;
  52. }
  53. else
  54. {
  55. Assert(NULL != pData);
  56. *ppData = pData;
  57. }
  58. FreeNetconProperties(pProps);
  59. TraceError("CChooseConnectionData::HrCreate",hr);
  60. return hr;
  61. }
  62. CChooseConnectionData::~CChooseConnectionData()
  63. {
  64. ReleaseObj(m_pConn);
  65. }
  66. CChooseConnectionDlg::CChooseConnectionDlg(NETCON_CHOOSECONN * pChooseConn,
  67. CConnectionCommonUi * pConnUi,
  68. INetConnection** ppConn)
  69. {
  70. Assert(pChooseConn);
  71. Assert(pConnUi);
  72. m_pChooseConn = pChooseConn;
  73. m_pConnUi = pConnUi;
  74. m_ppConn = ppConn; // The optional out parameter
  75. if (NULL != m_ppConn)
  76. {
  77. *m_ppConn = NULL;
  78. }
  79. m_hWnd = NULL;
  80. }
  81. CChooseConnectionDlg::~CChooseConnectionDlg()
  82. {
  83. m_pChooseConn = NULL;
  84. m_pConnUi = NULL;
  85. }
  86. HRESULT CChooseConnectionDlg::HrLoadImageList(HIMAGELIST * pIL)
  87. {
  88. UINT nIdx;
  89. HRESULT hr = E_OUTOFMEMORY;
  90. HIMAGELIST hIL = ImageList_Create(16, 16, TRUE, 6, 1);
  91. if (NULL == hIL)
  92. goto Error;
  93. for (nIdx=0; nIdx<celems(ConnTypeMap); nIdx++)
  94. {
  95. HICON hIcon = LoadIcon(_Module.GetResourceInstance(),
  96. MAKEINTRESOURCE(ConnTypeMap[nIdx].nIDI));
  97. Assert(NULL != hIcon);
  98. ConnTypeMap[nIdx].nIDI_Idx = ImageList_AddIcon(hIL, hIcon);
  99. if (-1 == ConnTypeMap[nIdx].nIDI_Idx)
  100. goto Error;
  101. }
  102. *pIL = hIL;
  103. hr = S_OK;
  104. Error:
  105. TraceError("CChooseConnectionDlg::HrLoadImageList",hr);
  106. return hr;
  107. }
  108. VOID CChooseConnectionDlg::ReleaseData()
  109. {
  110. if (NULL != m_hWnd)
  111. {
  112. HWND hwndCMB = GetDlgItem(m_hWnd, CMB_CHOOSER_LIST);
  113. LONG lCnt = (LONG)SendMessage(hwndCMB, CB_GETCOUNT, 0, 0);
  114. for (;lCnt>0;)
  115. {
  116. CChooseConnectionData * pData = GetData(--lCnt);
  117. delete pData;
  118. }
  119. SendMessage(hwndCMB, CB_RESETCONTENT, 0, 0);
  120. }
  121. }
  122. BOOL CChooseConnectionDlg::IsConnTypeInMask(NETCON_MEDIATYPE nct)
  123. {
  124. BOOL fFound = FALSE;
  125. for (UINT nIdx=0; nIdx<celems(ConnTypeMap); nIdx++)
  126. {
  127. if ((ConnTypeMap[nIdx].nct == nct) &&
  128. (ConnTypeMap[nIdx].ncct & m_pChooseConn->dwTypeMask))
  129. {
  130. fFound = TRUE;
  131. break;
  132. }
  133. }
  134. return fFound;
  135. }
  136. INT CChooseConnectionDlg::ConnTypeToImageIdx(NETCON_MEDIATYPE nct)
  137. {
  138. UINT nIdx;
  139. for (nIdx=0; nIdx<celems(ConnTypeMap); nIdx++)
  140. if (ConnTypeMap[nIdx].nct == nct)
  141. break;
  142. Assert(nIdx < celems(ConnTypeMap));;
  143. return ConnTypeMap[nIdx].nIDI_Idx;
  144. }
  145. LONG CChooseConnectionDlg::FillChooserCombo()
  146. {
  147. HRESULT hr;
  148. LONG lCnt = 0;
  149. COMBOBOXEXITEM CBItem = {0};
  150. HWND hwndCMB = GetDlgItem(m_hWnd, CMB_CHOOSER_LIST);
  151. // Free anything currently in the combo box
  152. ReleaseData();
  153. // Query new data for the combo box
  154. Assert(NULL != m_pConnUi->PConMan());
  155. INetConnection * pNetCon;
  156. CIterNetCon ncIter(m_pConnUi->PConMan(), NCME_DEFAULT);
  157. hr = S_OK;
  158. while (SUCCEEDED(hr) &&
  159. S_OK == (hr = ncIter.HrNext(&pNetCon)))
  160. {
  161. NETCON_PROPERTIES* pProps;
  162. hr = pNetCon->GetProperties(&pProps);
  163. if (SUCCEEDED(hr))
  164. {
  165. if (IsConnTypeInMask(pProps->MediaType))
  166. {
  167. CChooseConnectionData * pData = NULL;
  168. hr = CChooseConnectionData::HrCreate(pNetCon, &pData);
  169. if (SUCCEEDED(hr))
  170. {
  171. pData->SetCharacteristics(pProps->dwCharacter);
  172. pData->SetType(pProps->MediaType);
  173. pData->SetStatus(pProps->Status);
  174. CBItem.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_LPARAM | CBEIF_TEXT;
  175. CBItem.iItem = -1;
  176. CBItem.pszText = const_cast<PWSTR>(pData->SzName());
  177. CBItem.cchTextMax = lstrlenW(pData->SzName());
  178. CBItem.iImage = ConnTypeToImageIdx(pProps->MediaType);
  179. CBItem.iSelectedImage = CBItem.iImage;
  180. CBItem.lParam = reinterpret_cast<LPARAM>(pData);
  181. if (-1 != SendMessage(hwndCMB, CBEM_INSERTITEM, 0, (LPARAM)&CBItem))
  182. lCnt++;
  183. }
  184. }
  185. FreeNetconProperties(pProps);
  186. }
  187. ReleaseObj(pNetCon);
  188. }
  189. if (0 == lCnt)
  190. {
  191. // Add a "No connection found" line
  192. CBItem.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT;
  193. CBItem.iItem = -1;
  194. CBItem.pszText = const_cast<PWSTR>(SzLoadIds(IDS_NO_CONNECTIONS));
  195. CBItem.cchTextMax = lstrlenW(SzLoadIds(IDS_NO_CONNECTIONS));
  196. CBItem.iImage = ConnTypeToImageIdx(NCM_LAN);
  197. CBItem.iSelectedImage = CBItem.iImage;
  198. CBItem.lParam = NULL;
  199. if (-1 != SendMessage(hwndCMB, CBEM_INSERTITEM, 0, (LPARAM)&CBItem))
  200. {
  201. SendMessage(hwndCMB, CB_SETCURSEL, 0, 0);
  202. }
  203. }
  204. EnableWindow(hwndCMB, !!lCnt);
  205. TraceError("CChooseConnectionDlg::FillChooserCombo",hr==S_FALSE ? S_OK: hr);
  206. return lCnt;
  207. }
  208. CChooseConnectionData * CChooseConnectionDlg::GetData(LPARAM lIdx)
  209. {
  210. CChooseConnectionData * pData = NULL;
  211. HWND hwndCMB = GetDlgItem(m_hWnd, CMB_CHOOSER_LIST);
  212. COMBOBOXEXITEM CBItem = {0};
  213. CBItem.iItem = lIdx;
  214. CBItem.mask = CBEIF_LPARAM;
  215. if (0 != SendMessage(hwndCMB, CBEM_GETITEM, 0, (LPARAM)(PCOMBOBOXEXITEM) &CBItem))
  216. {
  217. pData = reinterpret_cast<CChooseConnectionData *>(CBItem.lParam);
  218. }
  219. return pData;
  220. }
  221. CChooseConnectionData * CChooseConnectionDlg::GetCurrentData()
  222. {
  223. HWND hwndCMB = GetDlgItem(m_hWnd, CMB_CHOOSER_LIST);
  224. LPARAM lParam = SendMessage(hwndCMB, CB_GETCURSEL, 0, 0);
  225. if (CB_ERR == lParam)
  226. return NULL;
  227. return GetData(lParam);
  228. }
  229. BOOL CChooseConnectionDlg::OnInitDialog(HWND hwndDlg)
  230. {
  231. HWND hwndOk = GetDlgItem(hwndDlg, BTN_CHOOSER_OK);
  232. HWND hwndCMB = GetDlgItem(hwndDlg, CMB_CHOOSER_LIST);
  233. m_hWnd = hwndDlg;
  234. // Set the caption text if necessary
  235. if (NCCHF_CAPTION & m_pChooseConn->dwFlags)
  236. {
  237. SetWindowText(m_hWnd, m_pChooseConn->lpstrCaption);
  238. }
  239. else if (NCCHF_CONNECT & m_pChooseConn->dwFlags)
  240. {
  241. SetWindowText(m_hWnd, SzLoadIds(IDS_CONNECT_CAPTION));
  242. }
  243. // Set the Ok text if necessary
  244. if (NCCHF_OKBTTNTEXT & m_pChooseConn->dwFlags)
  245. {
  246. SetWindowText(hwndOk, m_pChooseConn->lpstrOkBttnText);
  247. }
  248. else if (NCCHF_CONNECT & m_pChooseConn->dwFlags)
  249. {
  250. SetWindowText(hwndOk, SzLoadIds(IDS_OKBTTNTEXT));
  251. }
  252. // Disable the New button if requested or if the user doesn't
  253. // have rights for it.
  254. //
  255. if ((NCCHF_DISABLENEW & m_pChooseConn->dwFlags) ||
  256. !FHasPermission(NCPERM_NewConnectionWizard))
  257. {
  258. EnableWindow(GetDlgItem(m_hWnd, BTN_CHOOSER_NEW), FALSE);
  259. }
  260. // Populate the UI
  261. LONG lCnt = FillChooserCombo();
  262. Assert(NULL != m_pConnUi->HImageList());
  263. SendMessage(hwndCMB, CBEM_SETIMAGELIST, 0, (LPARAM)m_pConnUi->HImageList());
  264. ::SendMessage(hwndCMB, CB_SETCURSEL, 0, 0L);
  265. // Enable the buttons based on what was found
  266. UpdateOkState();
  267. // Special case, if they don't want to be able to create new connections
  268. // and we're in chooser mode and only one connection exists and the
  269. // autoselect option is selected, select it and return
  270. //
  271. if ((1 == lCnt) && (NCCHF_AUTOSELECT & m_pChooseConn->dwFlags) &&
  272. IsWindowEnabled(hwndOk))
  273. {
  274. PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(BTN_CHOOSER_OK, 0),
  275. (LPARAM)hwndOk);
  276. }
  277. return FALSE;
  278. }
  279. VOID CChooseConnectionDlg::UpdateOkState()
  280. {
  281. BOOL fEnabledOk = TRUE;
  282. BOOL fEnabledProps = TRUE;
  283. CChooseConnectionData * pData = GetCurrentData();
  284. if (NULL == pData)
  285. {
  286. fEnabledOk = FALSE;
  287. fEnabledProps = FALSE;
  288. }
  289. else
  290. {
  291. if (NCCHF_CONNECT & m_pChooseConn->dwFlags)
  292. {
  293. // If the current connection is not disconnected or if it's
  294. // a LAN/RAS connection and they don't have connect rights
  295. // then disable the OK button
  296. //
  297. if ((pData->ConnStatus() != NCS_DISCONNECTED) ||
  298. ((pData->ConnType() == NCM_LAN) && !FHasPermission(NCPERM_LanConnect)) ||
  299. ((pData->ConnType() != NCM_LAN) && !FHasPermission(NCPERM_RasConnect)))
  300. {
  301. fEnabledOk = FALSE;
  302. }
  303. }
  304. // If this is a LAN connection and the user doesn't have rights
  305. // then disallow properties
  306. //
  307. if ((NCM_LAN == pData->ConnType()) &&
  308. !FHasPermission(NCPERM_LanProperties))
  309. {
  310. fEnabledProps = FALSE;
  311. }
  312. // If this is a RAS connection and the user doesn't have rights
  313. // then disallow properties
  314. //
  315. if (NCM_LAN != pData->ConnType())
  316. {
  317. if (((pData->Characteristics() & NCCF_ALL_USERS) &&
  318. !FHasPermission(NCPERM_RasAllUserProperties)) ||
  319. !FHasPermission(NCPERM_RasMyProperties))
  320. {
  321. fEnabledProps = FALSE;
  322. }
  323. }
  324. }
  325. EnableWindow(GetDlgItem(m_hWnd, BTN_CHOOSER_OK), fEnabledOk);
  326. EnableWindow(GetDlgItem(m_hWnd, BTN_CHOOSER_PROPS), fEnabledProps);
  327. }
  328. BOOL CChooseConnectionDlg::OnNew()
  329. {
  330. INetConnection * pConn = NULL;
  331. HRESULT hr = m_pConnUi->StartNewConnectionWizard (m_hWnd, &pConn);
  332. if ((S_OK == hr) && (NULL != pConn))
  333. {
  334. NETCON_PROPERTIES * pProps = NULL;
  335. LONG lCnt = FillChooserCombo();
  336. int nIdx = CB_ERR;
  337. HWND hwndCMB = GetDlgItem(m_hWnd, CMB_CHOOSER_LIST);
  338. Assert(pConn);
  339. hr = pConn->GetProperties(&pProps);
  340. ReleaseObj(pConn);
  341. if (SUCCEEDED(hr) && lCnt && pProps->pszwName)
  342. {
  343. nIdx = (int)::SendMessage(hwndCMB, CB_FINDSTRINGEXACT,
  344. -1, (LPARAM)pProps->pszwName);
  345. }
  346. // Select whatever was found
  347. ::SendMessage(hwndCMB, CB_SETCURSEL, ((CB_ERR == nIdx) ? 0 : nIdx), 0L);
  348. UpdateOkState();
  349. FreeNetconProperties(pProps);
  350. }
  351. TraceErrorOptional("CChooseConnectionDlg::OnProps", hr, (S_FALSE==hr));
  352. return TRUE;
  353. }
  354. BOOL CChooseConnectionDlg::OnProps()
  355. {
  356. CChooseConnectionData * pData = GetCurrentData();
  357. if (NULL != pData)
  358. {
  359. HRESULT hr = m_pConnUi->ShowConnectionProperties(m_hWnd,
  360. pData->PConnection());
  361. TraceErrorOptional("CChooseConnectionDlg::OnProps", hr, (S_FALSE==hr));
  362. }
  363. return TRUE;
  364. }
  365. BOOL CChooseConnectionDlg::OnOk()
  366. {
  367. CChooseConnectionData * pData = GetCurrentData();
  368. if ((NULL != pData) && pData->PConnection())
  369. {
  370. if (m_ppConn)
  371. {
  372. *m_ppConn = pData->PConnection();
  373. (*m_ppConn)->AddRef();
  374. }
  375. // Launch the connection if we're in NCCHF_CONNECT mode
  376. if (NCCHF_CONNECT & m_pChooseConn->dwFlags)
  377. {
  378. Assert(*m_ppConn);
  379. HRESULT hr = HrConnectOrDisconnectNetConObject(
  380. m_hWnd, pData->PConnection(), CD_CONNECT);
  381. }
  382. EndDialog(m_hWnd, IDOK);
  383. }
  384. return TRUE;
  385. }
  386. INT_PTR CALLBACK
  387. CChooseConnectionDlg::dlgprocConnChooser(HWND hwndDlg, UINT uMsg,
  388. WPARAM wParam, LPARAM lParam)
  389. {
  390. BOOL frt = FALSE;
  391. LONG_PTR lTmp = ::GetWindowLongPtr(hwndDlg, DWLP_USER);
  392. CChooseConnectionDlg * pdlg = reinterpret_cast<CChooseConnectionDlg *>(lTmp);
  393. switch (uMsg)
  394. {
  395. case WM_INITDIALOG:
  396. {
  397. Assert(lParam);
  398. ::SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
  399. pdlg = reinterpret_cast<CChooseConnectionDlg *>(lParam);
  400. frt = pdlg->OnInitDialog(hwndDlg);
  401. }
  402. break;
  403. case WM_DESTROY:
  404. if (NULL != pdlg)
  405. {
  406. pdlg->ReleaseData();
  407. }
  408. break;
  409. case WM_COMMAND:
  410. switch (HIWORD(wParam))
  411. {
  412. case CBN_SELENDOK:
  413. if (LOWORD(wParam) == CMB_CHOOSER_LIST)
  414. {
  415. Assert(pdlg);
  416. pdlg->UpdateOkState();
  417. }
  418. break;
  419. case BN_CLICKED:
  420. switch (LOWORD(wParam))
  421. {
  422. case BTN_CHOOSER_NEW:
  423. Assert(pdlg);
  424. frt = pdlg->OnNew();
  425. break;
  426. case BTN_CHOOSER_PROPS:
  427. Assert(pdlg);
  428. frt = pdlg->OnProps();
  429. break;
  430. case BTN_CHOOSER_OK:
  431. Assert(pdlg);
  432. frt = pdlg->OnOk();
  433. break;
  434. case IDCANCEL:
  435. frt = TRUE;
  436. EndDialog(hwndDlg, IDCANCEL);
  437. break;
  438. }
  439. break;
  440. }
  441. break;
  442. default:
  443. frt = FALSE;
  444. break;
  445. }
  446. return frt;
  447. }