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.

358 lines
9.4 KiB

  1. // DhcpRouteArrayEditor.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "RouteArrayEditor.h"
  5. #include "optcfg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CDhcpRouteArrayEditor dialog
  13. CDhcpRouteArrayEditor::CDhcpRouteArrayEditor(
  14. CDhcpOption * pdhcType,
  15. DHCP_OPTION_SCOPE_TYPE dhcScopeType,
  16. CWnd *pParent )
  17. : CBaseDialog(CDhcpRouteArrayEditor::IDD, pParent),
  18. m_p_type( pdhcType ),
  19. m_option_type( dhcScopeType )
  20. {
  21. //{{AFX_DATA_INIT(CDhcpRouteArrayEditor)
  22. //}}AFX_DATA_INIT
  23. }
  24. void CDhcpRouteArrayEditor::DoDataExchange(CDataExchange* pDX)
  25. {
  26. CDialog::DoDataExchange(pDX);
  27. //{{AFX_DATA_MAP(CDhcpRouteArrayEditor)
  28. DDX_Control(pDX, IDC_STATIC_OPTION_NAME, m_st_option);
  29. DDX_Control(pDX, IDC_STATIC_APPLICATION, m_st_application);
  30. DDX_Control(pDX, IDC_LIST_OF_ROUTES, m_lc_routes);
  31. DDX_Control(pDX, IDC_BUTN_ROUTE_DELETE, m_butn_route_delete);
  32. DDX_Control(pDX, IDC_BUTN_ROUTE_ADD, m_butn_route_add);
  33. //}}AFX_DATA_MAP
  34. }
  35. BEGIN_MESSAGE_MAP(CDhcpRouteArrayEditor, CBaseDialog)
  36. //{{AFX_MSG_MAP(CDhcpRouteArrayEditor)
  37. ON_BN_CLICKED(IDC_BUTN_ROUTE_ADD, OnButnRouteAdd)
  38. ON_BN_CLICKED(IDC_BUTN_ROUTE_DELETE, OnButnRouteDelete)
  39. //}}AFX_MSG_MAP
  40. END_MESSAGE_MAP()
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CDhcpRouteArrayEditor message handlers
  43. void CDhcpRouteArrayEditor::OnButnRouteAdd()
  44. {
  45. CAddRoute NewRoute( NULL );
  46. NewRoute.DoModal();
  47. if ( NewRoute.m_bChange ) {
  48. const int IP_ADDR_LEN = 20;
  49. WCHAR strDest[ IP_ADDR_LEN ];
  50. WCHAR strMask[ IP_ADDR_LEN ];
  51. WCHAR strRouter[ IP_ADDR_LEN ];
  52. // obtain the three strings..
  53. ::UtilCvtIpAddrToWstr( NewRoute.Dest, strDest, IP_ADDR_LEN );
  54. ::UtilCvtIpAddrToWstr( NewRoute.Mask, strMask, IP_ADDR_LEN );
  55. ::UtilCvtIpAddrToWstr( NewRoute.Router, strRouter, IP_ADDR_LEN );
  56. LV_ITEM lvi;
  57. lvi.mask = LVIF_TEXT;
  58. lvi.iItem = m_lc_routes.GetItemCount();
  59. lvi.iSubItem = 0;
  60. lvi.pszText = ( LPTSTR )( LPCTSTR ) strDest;
  61. lvi.iImage = 0;
  62. lvi.stateMask = 0;
  63. int nItem = m_lc_routes.InsertItem( &lvi );
  64. m_lc_routes.SetItemText( nItem, 1, strMask );
  65. m_lc_routes.SetItemText( nItem, 2, strRouter );
  66. // unselect others
  67. for ( int i = 0; i < m_lc_routes.GetItemCount(); i++ ) {
  68. m_lc_routes.SetItemState( i, 0, LVIS_SELECTED );
  69. } // for
  70. // Make this route as selected item
  71. m_lc_routes.SetItemState( nItem, LVIS_SELECTED, LVIS_SELECTED );
  72. HandleActivation();
  73. } // if route added
  74. } // CDhcpRouteArrayEditor::OnButnRouteAdd()
  75. void CDhcpRouteArrayEditor::OnButnRouteDelete()
  76. {
  77. int nItem = m_lc_routes.GetNextItem( -1, LVNI_SELECTED );
  78. int nDelItem = 0;
  79. while ( nItem != -1 ) {
  80. m_lc_routes.DeleteItem( nItem );
  81. nDelItem = nItem;
  82. // Make the next one or the last one as selected
  83. nItem = m_lc_routes.GetNextItem( -1, LVNI_SELECTED );
  84. } // while
  85. // Select an item
  86. int items = m_lc_routes.GetItemCount();
  87. if ( items > 0 ) {
  88. if ( nDelItem >= items ) {
  89. nDelItem = items - 1;
  90. }
  91. m_lc_routes.SetItemState( nDelItem, LVIS_SELECTED, LVIS_SELECTED );
  92. } // if
  93. HandleActivation();
  94. } // CDhcpRouteArrayEditor::OnButnRouteDelete()
  95. void CDhcpRouteArrayEditor::OnCancel()
  96. {
  97. CBaseDialog::OnCancel();
  98. }
  99. void CDhcpRouteArrayEditor::OnOK()
  100. {
  101. DWORD err = 0;
  102. int nItems, BufSize;
  103. CListCtrl *pList;
  104. LPBYTE Buffer;
  105. // The following code is borrowed from
  106. // CDhcpOptCfgPropPage::HandleActivationRouteArray()
  107. nItems = m_lc_routes.GetItemCount();
  108. Buffer = new BYTE[ sizeof( DWORD ) * 4 * nItems ];
  109. if ( NULL == Buffer ) {
  110. return;
  111. }
  112. BufSize = 0;
  113. for ( int i = 0; i < nItems; i++ ) {
  114. DHCP_IP_ADDRESS Dest, Mask, Router;
  115. Dest = UtilCvtWstrToIpAddr( m_lc_routes.GetItemText( i, 0 ));
  116. Mask = UtilCvtWstrToIpAddr( m_lc_routes.GetItemText( i, 1 ));
  117. Router = UtilCvtWstrToIpAddr( m_lc_routes.GetItemText( i, 2 ));
  118. Dest = htonl( Dest );
  119. Router = htonl( Router );
  120. int nBitsInMask = 0;
  121. while ( Mask != 0 ) {
  122. nBitsInMask++;
  123. Mask <<= 1;
  124. }
  125. // first add destination descriptor
  126. // first byte contains # of bits in mask
  127. // next few bytes contain the dest address for only
  128. // the significant octets
  129. Buffer[ BufSize++ ] = ( BYTE ) nBitsInMask;
  130. memcpy( &Buffer[ BufSize ], &Dest, ( nBitsInMask + 7 ) / 8 );
  131. BufSize += ( nBitsInMask + 7 ) / 8;
  132. // now just copy the router address
  133. memcpy(& Buffer[ BufSize ], &Router, sizeof( Router ));
  134. BufSize += sizeof( Router );
  135. } // for
  136. // Now write back the option value
  137. DHCP_OPTION_DATA_ELEMENT DataElement = { DhcpBinaryDataOption };
  138. DHCP_OPTION_DATA Data = { 1, &DataElement };
  139. DataElement.Element.BinaryDataOption.DataLength = BufSize;
  140. DataElement.Element.BinaryDataOption.Data = Buffer;
  141. err = m_p_type->QueryValue().SetData( &Data );
  142. delete[] Buffer;
  143. m_p_type->SetDirty();
  144. if ( err ) {
  145. ::DhcpMessageBox( err );
  146. OnCancel();
  147. }
  148. else {
  149. CBaseDialog::OnOK();
  150. }
  151. } // CDhcpRouteArrayEditor::OnOK()
  152. //
  153. // strings and widths used for the list control
  154. //
  155. const int ROUTE_LIST_COL_HEADERS[3] = {
  156. IDS_ROUTE_LIST_COL_DEST,
  157. IDS_ROUTE_LIST_COL_MASK,
  158. IDS_ROUTE_LIST_COL_ROUTER
  159. };
  160. const int ROUTE_COLS =
  161. sizeof( ROUTE_LIST_COL_HEADERS ) / sizeof( ROUTE_LIST_COL_HEADERS[ 0 ]);
  162. BOOL CDhcpRouteArrayEditor::OnInitDialog()
  163. {
  164. CString strColHeader;
  165. RECT rect;
  166. LONG width;
  167. CDhcpOptionValue &optValue = m_p_type->QueryValue();
  168. // make sure the option type is set as Binary data type
  169. ASSERT( DhcpBinaryDataOption == optValue.QueryDataType());
  170. CBaseDialog::OnInitDialog();
  171. DWORD err = 0;
  172. int cStrId = ( m_option_type == DhcpDefaultOptions)
  173. ? IDS_INFO_TITLE_DEFAULT_OPTIONS
  174. : (( m_option_type == DhcpGlobalOptions )
  175. ? IDS_INFO_TITLE_GLOBAL_OPTIONS
  176. : IDS_INFO_TITLE_SCOPE_OPTIONS );
  177. //
  178. // setup the columns in the list control
  179. //
  180. m_lc_routes.GetClientRect( &rect );
  181. width = ( rect.right - rect.left ) / 3;
  182. for ( int i = 0; i < ROUTE_COLS; i++ ) {
  183. strColHeader.LoadString( ROUTE_LIST_COL_HEADERS[ i ] );
  184. m_lc_routes.InsertColumn( i, strColHeader, LVCFMT_LEFT,
  185. width, -1 );
  186. } // for
  187. // Select a full row
  188. m_lc_routes.SetExtendedStyle( m_lc_routes.GetExtendedStyle() |
  189. LVS_EX_FULLROWSELECT );
  190. const CByteArray *pbaData = optValue.QueryBinaryArray();
  191. ASSERT( pbaData != NULL );
  192. int nDataSize = ( int ) pbaData->GetSize();
  193. LPBYTE pData = ( LPBYTE ) pbaData->GetData();
  194. //
  195. // The following loop is copied from optcfg.cpp,
  196. // COptionsCfgPropPage::FillDataEntry()
  197. //
  198. while ( nDataSize > sizeof( DWORD )) {
  199. // first 1 byte contains the # of bits in subnetmask
  200. nDataSize --;
  201. BYTE nBitsMask = *pData ++;
  202. DWORD Mask = (~0);
  203. if( nBitsMask < 32 ) Mask <<= (32-nBitsMask);
  204. // based on the # of bits, the next few bytes contain
  205. // the subnet address for the 1-bits of subnet mask
  206. int nBytesDest = (nBitsMask+7)/8;
  207. if( nBytesDest > 4 ) nBytesDest = 4;
  208. DWORD Dest = 0;
  209. memcpy( &Dest, pData, nBytesDest );
  210. pData += nBytesDest;
  211. nDataSize -= nBytesDest;
  212. // subnet address is obviously in network order.
  213. Dest = ntohl(Dest);
  214. // now the four bytes would be the router address
  215. DWORD Router = 0;
  216. if( nDataSize < sizeof(DWORD) ) {
  217. Assert( FALSE ); break;
  218. }
  219. memcpy(&Router, pData, sizeof(DWORD));
  220. Router = ntohl( Router );
  221. pData += sizeof(DWORD);
  222. nDataSize -= sizeof(DWORD);
  223. // now fill the list box..
  224. const int IP_ADDR_LEN = 20;
  225. WCHAR strDest[ IP_ADDR_LEN ];
  226. WCHAR strMask[ IP_ADDR_LEN ];
  227. WCHAR strRouter[ IP_ADDR_LEN ];
  228. ::UtilCvtIpAddrToWstr( Dest, strDest, IP_ADDR_LEN );
  229. ::UtilCvtIpAddrToWstr( Mask, strMask, IP_ADDR_LEN );
  230. ::UtilCvtIpAddrToWstr( Router, strRouter, IP_ADDR_LEN );
  231. LV_ITEM lvi;
  232. lvi.mask = LVIF_TEXT;
  233. lvi.iItem = m_lc_routes.GetItemCount();
  234. lvi.iSubItem = 0;
  235. lvi.pszText = ( LPTSTR )( LPCTSTR ) strDest;
  236. lvi.iImage = 0;
  237. lvi.stateMask = 0;
  238. int nItem = m_lc_routes.InsertItem( &lvi );
  239. m_lc_routes.SetItemText( nItem, 1, strMask );
  240. m_lc_routes.SetItemText( nItem, 2, strRouter );
  241. } // while
  242. // set the first item as selected if any is added.
  243. if ( m_lc_routes.GetItemCount() > 0 ) {
  244. m_lc_routes.SetItemState( 0, LVIS_SELECTED, LVIS_SELECTED );
  245. }
  246. CATCH_MEM_EXCEPTION {
  247. CString str;
  248. m_st_option.SetWindowText( m_p_type->QueryName());
  249. str.LoadString( cStrId );
  250. m_st_application.SetWindowText( str );
  251. // Set proper button states.
  252. HandleActivation();
  253. }
  254. END_MEM_EXCEPTION( err );
  255. if ( err ) {
  256. ::DhcpMessageBox( err );
  257. EndDialog( -1 );
  258. }
  259. return TRUE; // return TRUE unless you set the focus to a control
  260. // EXCEPTION: OCX Property Pages should return FALSE
  261. } // CDhcpRouteArrayEditor::OnInitDialog()
  262. void CDhcpRouteArrayEditor::HandleActivation()
  263. {
  264. int cItems = m_lc_routes.GetItemCount();
  265. // set the focus to Add button
  266. m_butn_route_add.SetFocus();
  267. m_butn_route_delete.EnableWindow( 0 != cItems );
  268. UpdateData( FALSE );
  269. } // CDhcpRouteArrayEditor::HandleActivation()