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.

614 lines
14 KiB

  1. //============================================================================
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: conndlg.cpp
  5. //
  6. // History:
  7. // 09/22/96 Abolade Gbadegesin Created.
  8. //
  9. // Implementation of the connection-status dialog.
  10. //============================================================================
  11. #include "stdafx.h"
  12. #include "dialog.h"
  13. #include "rtrutilp.h"
  14. //nclude "ddmadmin.h"
  15. //nclude "ddmroot.h"
  16. extern "C" {
  17. //nclude "dim.h"
  18. #include "ras.h"
  19. }
  20. #include "conndlg.h"
  21. #include "rtrstr.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. //----------------------------------------------------------------------------
  28. // Class: CConnDlg
  29. //
  30. //----------------------------------------------------------------------------
  31. //----------------------------------------------------------------------------
  32. // Function: CConnDlg::CConnDlg
  33. //
  34. // Constructor: initialize the base-class and the dialog's data.
  35. //----------------------------------------------------------------------------
  36. CConnDlg::CConnDlg(
  37. HANDLE hServer,
  38. HANDLE hConnection,
  39. ITFSNode* pDialInNode,
  40. CWnd* pParent
  41. ) : CBaseDialog(IDD_DDM_CONN, pParent)
  42. {
  43. m_hServer = hServer;
  44. m_hConnection = hConnection;
  45. // m_spDialInNode = pDialInNode;
  46. m_bChanged = FALSE;
  47. }
  48. //----------------------------------------------------------------------------
  49. // Function: CConnDlg::DoDataExchange
  50. //
  51. // DDX handler.
  52. //----------------------------------------------------------------------------
  53. VOID
  54. CConnDlg::DoDataExchange(
  55. CDataExchange* pDX
  56. ) {
  57. CBaseDialog::DoDataExchange(pDX);
  58. DDX_Control(pDX, IDC_DC_COMBO_CONNLIST, m_cbConnections);
  59. }
  60. BEGIN_MESSAGE_MAP(CConnDlg, CBaseDialog)
  61. ON_COMMAND(IDC_DC_BTN_RESET, OnReset)
  62. ON_COMMAND(IDC_DC_BTN_HANGUP, OnHangUp)
  63. ON_COMMAND(IDC_DC_BTN_REFRESH, OnRefresh)
  64. ON_CBN_SELENDOK(IDC_DC_COMBO_CONNLIST, OnSelendokConnList)
  65. END_MESSAGE_MAP()
  66. BOOL
  67. CConnDlg::OnInitDialog(
  68. ) {
  69. CBaseDialog::OnInitDialog();
  70. RefreshItem(m_hConnection);
  71. return FALSE;
  72. }
  73. BOOL
  74. CConnDlg::RefreshItem(
  75. HANDLE hConnection,
  76. BOOL bDisconnected
  77. ) {
  78. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  79. DWORD dwErr, dwTotal;
  80. DWORD rp0Count, rc0Count;
  81. BYTE* rp0Table, *rc0Table;
  82. BOOL bChanged = FALSE;
  83. rp0Table = rc0Table = 0;
  84. rp0Count = 0;
  85. do {
  86. //
  87. // Retrieve an array of ports
  88. //
  89. /*--ft: actually this is never needed in this context
  90. dwErr = ::MprAdminPortEnum(
  91. m_hServer,
  92. 0,
  93. INVALID_HANDLE_VALUE,
  94. (BYTE**)&rp0Table,
  95. (DWORD)-1,
  96. &rp0Count,
  97. &dwTotal,
  98. NULL
  99. );
  100. if (dwErr != NO_ERROR) { break; }
  101. */
  102. //
  103. // Retrieve an array of connections
  104. //
  105. dwErr = ::MprAdminConnectionEnum(
  106. m_hServer,
  107. 0,
  108. (BYTE**)&rc0Table,
  109. (DWORD)-1,
  110. &rc0Count,
  111. &dwTotal,
  112. NULL
  113. );
  114. if (dwErr != NO_ERROR) { break; }
  115. // if the caller signals this connection to be terminated, we remove its record from the
  116. // array returned by MprAdminConnectionEnum().
  117. if (bDisconnected)
  118. {
  119. INT i;
  120. RAS_CONNECTION_0* prc0;
  121. for (i = 0, prc0 = (RAS_CONNECTION_0*)rc0Table; i < (INT)rc0Count; i++, prc0++)
  122. {
  123. // if the record to delete was found, just move the memory over it and update rc0Count.
  124. // the memory will still be freed by MprAdminBufferFree().
  125. if (prc0->hConnection == hConnection)
  126. {
  127. if (i != (INT)(rc0Count - 1))
  128. {
  129. // MoveMemory(dest, src, size)
  130. MoveMemory(prc0, prc0+1, (rc0Count - (i + 1))*sizeof(RAS_CONNECTION_0));
  131. }
  132. rc0Count--;
  133. break;
  134. }
  135. }
  136. }
  137. //
  138. // Do the refresh of the display,
  139. // selecting the item specified by the caller.
  140. //
  141. bChanged = Refresh(rp0Table, rp0Count, rc0Table, rc0Count, hConnection);
  142. dwErr = NO_ERROR;
  143. } while (FALSE);
  144. if (rc0Table) { ::MprAdminBufferFree(rc0Table); }
  145. if (rp0Table) { ::MprAdminBufferFree(rp0Table); }
  146. if (dwErr != NO_ERROR) {
  147. TCHAR szText[1024];
  148. FormatSystemError(HRESULT_FROM_WIN32(dwErr),
  149. szText, DimensionOf(szText),
  150. IDS_ERR_INITDLGERROR, FSEFLAG_ANYMESSAGE);
  151. AfxMessageBox(szText);
  152. EndDialog(IDCANCEL);
  153. }
  154. return bChanged;
  155. }
  156. VOID
  157. CConnDlg::OnHangUp(
  158. ) {
  159. INT iSel;
  160. DWORD dwErr;
  161. HANDLE hConnection;
  162. RAS_CONNECTION_0* prc0;
  163. CWaitCursor wait;
  164. iSel = m_cbConnections.GetCurSel();
  165. if (iSel == CB_ERR) { return; }
  166. //
  167. // Get the connection to be hung up
  168. //
  169. hConnection = (HANDLE)m_cbConnections.GetItemData(iSel);
  170. //
  171. // Retrieve the interface for this connection;
  172. // we then hang up the connection by disconnecting its interface
  173. //
  174. dwErr = ::MprAdminConnectionGetInfo(
  175. m_hServer,
  176. 0,
  177. hConnection,
  178. (BYTE**)&prc0
  179. );
  180. if (dwErr == NO_ERROR && prc0) {
  181. //
  182. // Disconnect the connections interface
  183. //
  184. dwErr = ::MprAdminInterfaceDisconnect(
  185. m_hServer,
  186. prc0->hInterface
  187. );
  188. ::MprAdminBufferFree(prc0);
  189. m_bChanged |= RefreshItem(hConnection, dwErr == NO_ERROR);
  190. }
  191. }
  192. VOID
  193. CConnDlg::OnReset(
  194. ) {
  195. INT iSel;
  196. HANDLE hConnection;
  197. iSel = m_cbConnections.GetCurSel();
  198. if (iSel == CB_ERR) { return; }
  199. hConnection = (HANDLE)m_cbConnections.GetItemData(iSel);
  200. ::MprAdminConnectionClearStats(
  201. m_hServer,
  202. hConnection
  203. );
  204. m_bChanged |= RefreshItem(INVALID_HANDLE_VALUE);
  205. }
  206. VOID
  207. CConnDlg::OnSelendokConnList(
  208. ) {
  209. m_bChanged |= RefreshItem(INVALID_HANDLE_VALUE);
  210. }
  211. VOID
  212. CConnDlg::OnRefresh(
  213. ) {
  214. m_bChanged |= RefreshItem(INVALID_HANDLE_VALUE);
  215. }
  216. BOOL
  217. CConnDlg::Refresh(
  218. BYTE* rp0Table,
  219. DWORD rp0Count,
  220. BYTE* rc0Table,
  221. DWORD rc0Count,
  222. VOID* pParam
  223. ) {
  224. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  225. DWORD dwErr;
  226. CString sItem;
  227. RAS_PORT_0* prp0;
  228. RAS_PORT_1* prp1;
  229. RAS_CONNECTION_0* prc0;
  230. RAS_CONNECTION_1* prc1;
  231. INT i, j, iSel, count;
  232. HANDLE hConnection, hConnSel = NULL, *pConnTable;
  233. TCHAR szNumber[32];
  234. BOOL bChanged = FALSE;
  235. hConnSel = (HANDLE)pParam;
  236. //
  237. // Fill an array of connection-handles with the connections which are
  238. // already in the combobox.
  239. //
  240. count = m_cbConnections.GetCount();
  241. if (count) {
  242. pConnTable = new HANDLE[count];
  243. }
  244. for (i = 0; i < count; i++) {
  245. pConnTable[i] = (HANDLE)m_cbConnections.GetItemData(i);
  246. }
  247. //
  248. // Refresh the combobox with connection-names;
  249. // We do this in two passes, first adding the names of connections
  250. // which aren't already in the combobox,
  251. // and then removing the names of connections which aren't
  252. // in the table of connections ('rc0Table').
  253. //
  254. for (i = 0, prc0 = (RAS_CONNECTION_0*)rc0Table; i < (INT)rc0Count;
  255. i++, prc0++) {
  256. //
  257. // See if connection 'i' is already in the combobox.
  258. //
  259. for (j = 0; j < count; j++) {
  260. if (pConnTable[j] == prc0->hConnection) { break; }
  261. }
  262. if (j < count) { continue; }
  263. //
  264. // Connection 'i' isn't already in the combobox, so add it.
  265. //
  266. sItem.Format(TEXT("%ls"), prc0->wszInterfaceName);
  267. iSel = m_cbConnections.AddString(sItem);
  268. if (iSel >= 0) {
  269. m_cbConnections.SetItemData(iSel, reinterpret_cast<ULONG_PTR>(prc0->hConnection));
  270. if (prc0->hConnection == hConnSel) {
  271. m_cbConnections.SetCurSel(iSel);
  272. }
  273. bChanged = TRUE;
  274. }
  275. }
  276. if (count) { delete [] pConnTable; }
  277. //
  278. // Second stage: remove all connections which aren't in 'rc0Table'.
  279. // This is only necessary if there were any connections in the combobox
  280. // before.
  281. //
  282. if (count > 0) {
  283. count = m_cbConnections.GetCount();
  284. for (i = 0; i < count; i++) {
  285. hConnection = (HANDLE)m_cbConnections.GetItemData(i);
  286. //
  287. // See if the connection is in 'rc0Table'.
  288. //
  289. for (j = 0, prc0 = (RAS_CONNECTION_0*)rc0Table; j < (INT)rc0Count;
  290. j++, prc0++) {
  291. if (prc0->hConnection == hConnection) { break; }
  292. }
  293. if (j < (INT)rc0Count) {
  294. if (prc0->hConnection == hConnSel) {
  295. m_cbConnections.SetCurSel(i);
  296. }
  297. continue;
  298. }
  299. //
  300. // The connection wasn't found in 'rc0Table',
  301. // so remove it from the combobox,
  302. // and adjust the enumeration indices.
  303. //
  304. m_cbConnections.DeleteString(i);
  305. --i; --count;
  306. bChanged = TRUE;
  307. }
  308. }
  309. // Clear out the address fields
  310. SetDlgItemText(IDC_DC_TEXT_IPADDRESS, c_szEmpty);
  311. SetDlgItemText(IDC_DC_TEXT_IPXADDRESS, c_szEmpty);
  312. SetDlgItemText(IDC_DC_TEXT_NBFADDRESS, c_szEmpty);
  313. SetDlgItemText(IDC_DC_TEXT_ATLKADDRESS, c_szEmpty);
  314. // Clear out the line bps field
  315. SetDlgItemText(IDC_DC_TEXT_DURATION, c_szEmpty);
  316. SetDlgItemText(IDC_DC_TEXT_BYTESIN, c_szEmpty);
  317. SetDlgItemText(IDC_DC_TEXT_BYTESOUT, c_szEmpty);
  318. SetDlgItemText(IDC_DC_TEXT_FRAMESIN, c_szEmpty);
  319. SetDlgItemText(IDC_DC_TEXT_FRAMESOUT, c_szEmpty);
  320. SetDlgItemText(IDC_DC_TEXT_COMPIN, c_szEmpty);
  321. SetDlgItemText(IDC_DC_TEXT_COMPOUT, c_szEmpty);
  322. SetDlgItemText(IDC_DC_TEXT_TIMEOUT, c_szEmpty);
  323. SetDlgItemText(IDC_DC_TEXT_ALIGNMENT, c_szEmpty);
  324. SetDlgItemText(IDC_DC_TEXT_FRAMING, c_szEmpty);
  325. SetDlgItemText(IDC_DC_TEXT_HWOVERRUN, c_szEmpty);
  326. SetDlgItemText(IDC_DC_TEXT_BUFOVERRUN, c_szEmpty);
  327. SetDlgItemText(IDC_DC_TEXT_CRC, c_szEmpty);
  328. //
  329. // If there is no selection select the first item
  330. //
  331. if ((iSel = m_cbConnections.GetCurSel()) == CB_ERR) {
  332. iSel = m_cbConnections.SetCurSel(0);
  333. }
  334. if (iSel == CB_ERR)
  335. {
  336. if (GetFocus() == GetDlgItem(IDC_DC_BTN_HANGUP))
  337. GetDlgItem(IDC_DC_BTN_RESET)->SetFocus();
  338. GetDlgItem(IDC_DC_BTN_HANGUP)->EnableWindow(FALSE);
  339. return bChanged;
  340. }
  341. //
  342. // Update the display with information for the selected item
  343. //
  344. hConnection = (HANDLE)m_cbConnections.GetItemData(iSel);
  345. for (i = 0, prc0 = (RAS_CONNECTION_0*)rc0Table; i < (INT)rc0Count;
  346. i++, prc0++) {
  347. if (prc0->hConnection == hConnection) { break; }
  348. }
  349. if (i >= (INT)rc0Count) { return bChanged; }
  350. //
  351. // First update the RAS_CONNECTION_0-based information
  352. //
  353. FormatDuration(prc0->dwConnectDuration, sItem, UNIT_SECONDS);
  354. SetDlgItemText(IDC_DC_TEXT_DURATION, sItem);
  355. do {
  356. //
  357. // Now retrieve the RAS_CONNECTION_1 information for this connection.
  358. //
  359. dwErr = ::MprAdminConnectionGetInfo(
  360. m_hServer,
  361. 1,
  362. prc0->hConnection,
  363. (BYTE**)&prc1
  364. );
  365. if (dwErr != NO_ERROR || !prc1) { break; }
  366. //
  367. // Set the information in the dialog text-controls
  368. //
  369. FormatNumber(prc1->dwBytesRcved, szNumber, DimensionOf(szNumber), FALSE);
  370. SetDlgItemText(IDC_DC_TEXT_BYTESIN, szNumber);
  371. FormatNumber(prc1->dwBytesXmited, szNumber, DimensionOf(szNumber), FALSE);
  372. SetDlgItemText(IDC_DC_TEXT_BYTESOUT, szNumber);
  373. FormatNumber(prc1->dwFramesRcved, szNumber, DimensionOf(szNumber), FALSE);
  374. SetDlgItemText(IDC_DC_TEXT_FRAMESIN, szNumber);
  375. FormatNumber(prc1->dwFramesXmited, szNumber, DimensionOf(szNumber), FALSE);
  376. SetDlgItemText(IDC_DC_TEXT_FRAMESOUT, szNumber);
  377. FormatNumber(prc1->dwCompressionRatioIn, szNumber, DimensionOf(szNumber), FALSE);
  378. sItem = szNumber;
  379. sItem += TEXT( "%" );
  380. SetDlgItemText(IDC_DC_TEXT_COMPIN, sItem);
  381. FormatNumber(prc1->dwCompressionRatioOut, szNumber, DimensionOf(szNumber), FALSE);
  382. sItem = szNumber;
  383. sItem += TEXT( "%" );
  384. SetDlgItemText(IDC_DC_TEXT_COMPOUT, sItem);
  385. FormatNumber(prc1->dwCrcErr, szNumber, DimensionOf(szNumber), FALSE);
  386. SetDlgItemText(IDC_DC_TEXT_CRC, szNumber);
  387. FormatNumber(prc1->dwTimeoutErr, szNumber, DimensionOf(szNumber), FALSE);
  388. SetDlgItemText(IDC_DC_TEXT_TIMEOUT, szNumber);
  389. FormatNumber(prc1->dwAlignmentErr, szNumber, DimensionOf(szNumber), FALSE);
  390. SetDlgItemText(IDC_DC_TEXT_ALIGNMENT, szNumber);
  391. FormatNumber(prc1->dwFramingErr, szNumber, DimensionOf(szNumber), FALSE);
  392. SetDlgItemText(IDC_DC_TEXT_FRAMING, szNumber);
  393. FormatNumber(prc1->dwHardwareOverrunErr, szNumber, DimensionOf(szNumber), FALSE);
  394. SetDlgItemText(IDC_DC_TEXT_HWOVERRUN, szNumber);
  395. FormatNumber(prc1->dwBufferOverrunErr, szNumber, DimensionOf(szNumber), FALSE);
  396. SetDlgItemText(IDC_DC_TEXT_BUFOVERRUN, szNumber);
  397. //
  398. // Fill in the network registration info for projected networks.
  399. //
  400. if (prc1->PppInfo.ip.dwError == NO_ERROR) {
  401. SetDlgItemTextW(IDC_DC_TEXT_IPADDRESS, prc1->PppInfo.ip.wszRemoteAddress);
  402. }
  403. if (prc1->PppInfo.ipx.dwError == NO_ERROR) {
  404. SetDlgItemTextW(IDC_DC_TEXT_IPXADDRESS, prc1->PppInfo.ipx.wszAddress);
  405. }
  406. if (prc1->PppInfo.nbf.dwError == NO_ERROR) {
  407. SetDlgItemTextW(IDC_DC_TEXT_NBFADDRESS, prc1->PppInfo.nbf.wszWksta);
  408. }
  409. if (prc1->PppInfo.at.dwError == NO_ERROR) {
  410. SetDlgItemTextW(IDC_DC_TEXT_ATLKADDRESS, prc1->PppInfo.at.wszAddress);
  411. }
  412. ::MprAdminBufferFree(prc1);
  413. } while (FALSE);
  414. if (dwErr != NO_ERROR) {
  415. TCHAR szText[1024];
  416. FormatSystemError(HRESULT_FROM_WIN32(dwErr),
  417. szText, DimensionOf(szText),
  418. IDS_ERR_INITDLGERROR, FSEFLAG_ANYMESSAGE);
  419. AfxMessageBox(szText);
  420. EndDialog(IDCANCEL);
  421. }
  422. return bChanged;
  423. }