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.

3032 lines
97 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation **/
  4. /**********************************************************************/
  5. /*
  6. optcfg.cpp
  7. Individual option property page
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "optcfg.h"
  12. #include "listview.h"
  13. #include "server.h"
  14. #include "nodes.h"
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. #define MAX_COLUMNS 2
  21. UINT COLUMN_HEADERS[MAX_COLUMNS] =
  22. {
  23. IDS_OPTCFG_NAME,
  24. IDS_OPTCFG_COMMENT
  25. };
  26. int COLUMN_WIDTHS[MAX_COLUMNS] =
  27. {
  28. 150, 175
  29. };
  30. const DWORD * OPTION_CONTROL_HELP_ARRAYS[] =
  31. {
  32. g_aHelpIDs_IDD_DATA_ENTRY_DWORD,
  33. g_aHelpIDs_IDD_DATA_ENTRY_IPADDRESS,
  34. g_aHelpIDs_IDD_DATA_ENTRY_IPADDRESS_ARRAY,
  35. g_aHelpIDs_IDD_DATA_ENTRY_BINARY,
  36. g_aHelpIDs_IDD_DATA_ENTRY_BINARY_ARRAY,
  37. g_aHelpIDs_IDD_DATA_ENTRY_STRING,
  38. g_aHelpIDs_IDD_DATA_ENTRY_ROUTE_ARRAY,
  39. g_aHelpIDs_IDD_DATA_ENTRY_STRING_ARRAY
  40. };
  41. // class CHelpMap
  42. CHelpMap::CHelpMap()
  43. {
  44. m_pdwHelpMap = NULL;
  45. }
  46. CHelpMap::~CHelpMap()
  47. {
  48. ResetMap();
  49. }
  50. void
  51. CHelpMap::BuildMap(DWORD pdwParentHelpMap[])
  52. {
  53. int i, j, nPos;
  54. int nSize = 0;
  55. int nCurSize;
  56. ResetMap();
  57. // calculate the size of the map
  58. // subtract off the terminators
  59. nSize += CountMap(pdwParentHelpMap);
  60. for (i = 0; i < ARRAYLEN(OPTION_CONTROL_HELP_ARRAYS); i++)
  61. {
  62. nSize += CountMap(OPTION_CONTROL_HELP_ARRAYS[i]);
  63. }
  64. nSize += 2; // for terminator
  65. m_pdwHelpMap = new DWORD[nSize];
  66. memset(m_pdwHelpMap, 0, sizeof(*m_pdwHelpMap));
  67. // fill in the parent help map
  68. nPos = 0;
  69. nCurSize = CountMap(pdwParentHelpMap);
  70. for (i = 0; i < nCurSize; i++)
  71. {
  72. m_pdwHelpMap[nPos++] = pdwParentHelpMap[i++];
  73. m_pdwHelpMap[nPos++] = pdwParentHelpMap[i];
  74. }
  75. // now add all of the possible option control help maps
  76. for (i = 0; i < ARRAYLEN(OPTION_CONTROL_HELP_ARRAYS); i++)
  77. {
  78. nCurSize = CountMap(OPTION_CONTROL_HELP_ARRAYS[i]);
  79. for (j = 0; j < nCurSize; j++)
  80. {
  81. m_pdwHelpMap[nPos++] = (OPTION_CONTROL_HELP_ARRAYS[i])[j++];
  82. m_pdwHelpMap[nPos++] = (OPTION_CONTROL_HELP_ARRAYS[i])[j];
  83. }
  84. }
  85. }
  86. DWORD * CHelpMap::GetMap()
  87. {
  88. return m_pdwHelpMap;
  89. }
  90. int CHelpMap::CountMap(const DWORD * pdwHelpMap)
  91. {
  92. int i = 0;
  93. while (pdwHelpMap[i] != 0)
  94. {
  95. i++;
  96. }
  97. return i++;
  98. }
  99. void CHelpMap::ResetMap()
  100. {
  101. if (m_pdwHelpMap)
  102. {
  103. delete m_pdwHelpMap;
  104. m_pdwHelpMap = NULL;
  105. }
  106. }
  107. DEBUG_DECLARE_INSTANCE_COUNTER(COptionsConfig);
  108. /////////////////////////////////////////////////////////////////////////////
  109. //
  110. // COptionsConfig holder
  111. //
  112. /////////////////////////////////////////////////////////////////////////////
  113. COptionsConfig::COptionsConfig
  114. (
  115. ITFSNode * pNode,
  116. ITFSNode * pServerNode,
  117. IComponentData * pComponentData,
  118. ITFSComponentData * pTFSCompData,
  119. COptionValueEnum * pOptionValueEnum,
  120. LPCTSTR pszSheetName,
  121. CDhcpOptionItem * pSelOption
  122. ) : CPropertyPageHolderBase(pNode, pComponentData, pszSheetName)
  123. {
  124. DEBUG_INCREMENT_INSTANCE_COUNTER(COptionsConfig);
  125. //ASSERT(pFolderNode == GetContainerNode());
  126. m_bAutoDeletePages = FALSE; // we have the pages as embedded members
  127. AddPageToList((CPropertyPageBase*) &m_pageGeneral);
  128. LARGE_INTEGER liServerVersion;
  129. CDhcpServer * pServer = GETHANDLER(CDhcpServer, pServerNode);
  130. pServer->GetVersion(m_liServerVersion);
  131. if (m_liServerVersion.QuadPart >= DHCP_NT5_VERSION)
  132. {
  133. AddPageToList((CPropertyPageBase*) &m_pageAdvanced);
  134. }
  135. Assert(pTFSCompData != NULL);
  136. m_spTFSCompData.Set(pTFSCompData);
  137. m_spServerNode.Set(pServerNode);
  138. // get all of the active options for this node
  139. SPITFSNode spNode;
  140. spNode = GetNode();
  141. m_bInitialized = FALSE;
  142. m_pOptionValueEnum = pOptionValueEnum;
  143. if (pSelOption)
  144. {
  145. m_strStartVendor = pSelOption->GetVendor();
  146. m_strStartClass = pSelOption->GetClassName();
  147. m_dhcpStartId = pSelOption->GetOptionId();
  148. }
  149. else
  150. {
  151. m_dhcpStartId = 0xffffffff;
  152. }
  153. }
  154. COptionsConfig::~COptionsConfig()
  155. {
  156. DEBUG_DECREMENT_INSTANCE_COUNTER(COptionsConfig);
  157. RemovePageFromList((CPropertyPageBase*) &m_pageGeneral, FALSE);
  158. RemovePageFromList((CPropertyPageBase*) &m_pageAdvanced, FALSE);
  159. }
  160. DWORD
  161. COptionsConfig::InitData()
  162. {
  163. DWORD dwErr = NO_ERROR;
  164. if (m_bInitialized)
  165. return dwErr;
  166. CDhcpServer * pServer = GETHANDLER(CDhcpServer, m_spServerNode);
  167. CClassInfoArray ClassInfoArray;
  168. pServer->GetClassInfoArray(ClassInfoArray);
  169. // create a standard DHCP options vendor tracker and a set of default class options
  170. CVendorTracker * pVendorTracker = AddVendorTracker(_T(""));
  171. AddClassTracker(pVendorTracker, _T(""));
  172. // walk the list of classes. For each vendor class, add a default user class.
  173. for (int i = 0; i < ClassInfoArray.GetSize(); i++)
  174. {
  175. if (ClassInfoArray[i].bIsVendor)
  176. {
  177. // create a vendor tracker and a set of default class options
  178. pVendorTracker = AddVendorTracker(ClassInfoArray[i].strName);
  179. AddClassTracker(pVendorTracker, _T(""));
  180. }
  181. }
  182. // now walk the list of vendor classes and add User class option lists
  183. POSITION pos = m_listVendorClasses.GetHeadPosition();
  184. while (pos)
  185. {
  186. pVendorTracker = m_listVendorClasses.GetNext(pos);
  187. // now build option sets for each user class in each vendor
  188. for (int j = 0; j < ClassInfoArray.GetSize(); j++)
  189. {
  190. if (!ClassInfoArray[j].bIsVendor)
  191. AddClassTracker(pVendorTracker, ClassInfoArray[j].strName);
  192. }
  193. }
  194. // now we need to update any active options with their current values
  195. UpdateActiveOptions();
  196. m_bInitialized = TRUE;
  197. return dwErr;
  198. }
  199. void
  200. COptionsConfig::SetTitle()
  201. {
  202. HWND hSheet = GetSheetWindow();
  203. ::SetWindowText(hSheet, m_stSheetTitle);
  204. }
  205. LPWSTR COptionsConfig::GetServerAddress()
  206. {
  207. CDhcpServer * pServer = GETHANDLER(CDhcpServer, m_spServerNode);
  208. return (LPWSTR) pServer->GetIpAddress();
  209. }
  210. CVendorTracker *
  211. COptionsConfig::AddVendorTracker(LPCTSTR pClassName)
  212. {
  213. CVendorTracker * pVendorTracker = new CVendorTracker();
  214. pVendorTracker->SetClassName(pClassName);
  215. m_listVendorClasses.AddTail(pVendorTracker);
  216. return pVendorTracker;
  217. }
  218. void COptionsConfig::AddClassTracker(CVendorTracker * pVendorTracker, LPCTSTR pClassName)
  219. {
  220. SPITFSNode spServerNode;
  221. spServerNode = GetServerNode();
  222. CDhcpServer * pServer = GETHANDLER(CDhcpServer, spServerNode);
  223. CClassTracker * pClassTracker = new CClassTracker();
  224. pClassTracker->SetClassName(pClassName);
  225. // add the new class tracker to the list.
  226. pVendorTracker->m_listUserClasses.AddTail(pClassTracker);
  227. // Get a pointer to the list of options on the server. We use this
  228. // to build our list of available options for this class
  229. CDhcpOption * pCurOption;
  230. CDhcpDefaultOptionsOnServer * pDefOptions = pServer->GetDefaultOptionsList();
  231. CString strVendor = pVendorTracker->GetClassName();
  232. CString strUserClass = pClassName;
  233. pCurOption = pDefOptions->First();
  234. while (pCurOption) {
  235. DHCP_OPTION_ID id = pCurOption->QueryId();
  236. // we filter out some options:
  237. // 1 - standard options with no user class call FilterOption
  238. // 2 - standard options with a user class call FilterUserClassOptions
  239. if ( (strVendor.IsEmpty() && !FilterOption(id) && !pCurOption->IsVendor()) ||
  240. (strVendor.IsEmpty() && !pCurOption->IsVendor() &&
  241. !strUserClass.IsEmpty() && !FilterUserClassOption(id)) ||
  242. (pCurOption->GetVendor() && strVendor.Compare(pCurOption->GetVendor()) == 0) )
  243. {
  244. // create an option item for this entry. We do this because
  245. // these options are stored in the server node, but since this is a modeless
  246. // dialog the values could change, so we'll take a snapshot of the data
  247. // we can just use the copy constructor of the CDhcpOption
  248. COptionTracker * pOptionTracker = new COptionTracker;
  249. CDhcpOption * pNewOption = new CDhcpOption(*pCurOption);
  250. pOptionTracker->m_pOption = pNewOption;
  251. // add the option to the class tracker
  252. pClassTracker->m_listOptions.AddTail(pOptionTracker);
  253. }
  254. pCurOption = pDefOptions->Next();
  255. }
  256. }
  257. void COptionsConfig::UpdateActiveOptions()
  258. {
  259. // Now the known options are in the correct locations. We need to see
  260. // what options are enabled for this node. We querried the server to make
  261. // sure we have the latest information about active options.
  262. m_pOptionValueEnum->Reset();
  263. CDhcpOption * pOption;
  264. while (pOption = m_pOptionValueEnum->Next()) {
  265. DHCP_OPTION_ID optionId = pOption->QueryId();
  266. // search all vendors options
  267. POSITION pos = m_listVendorClasses.GetHeadPosition();
  268. while (pos) {
  269. // search all vendor classes
  270. CVendorTracker * pVendorTracker = m_listVendorClasses.GetNext(pos);
  271. CString strVendor = pOption->GetVendor();
  272. if (pVendorTracker->m_strClassName.Compare(strVendor) == 0) {
  273. // ok, the vendor class matches so lets check user classes
  274. POSITION pos2 = pVendorTracker->m_listUserClasses.GetHeadPosition();
  275. while (pos2) {
  276. CClassTracker * pClassTracker = pVendorTracker->m_listUserClasses.GetNext(pos2);
  277. // check to see if this option belongs to this class
  278. if ( (pClassTracker->m_strClassName.IsEmpty()) &&
  279. (!pOption->IsClassOption()) ) {
  280. // both are empty... match.
  281. }
  282. else if (( pClassTracker->m_strClassName.IsEmpty() && pOption->IsClassOption()) ||
  283. ( !pClassTracker->m_strClassName.IsEmpty() && !pOption->IsClassOption())) {
  284. // either the current option or the current class is null...
  285. continue;
  286. }
  287. else if (pClassTracker->m_strClassName.CompareNoCase(pOption->GetClassName()) != 0) {
  288. // both names are non-null and they don't match... keep looking
  289. continue;
  290. }
  291. // Ok, the class the option belong to is the same as the one we are currently
  292. // looking at. Loop through the default options for this class and update it's
  293. // state and value.
  294. POSITION posOption = pClassTracker->m_listOptions.GetHeadPosition();
  295. while (posOption) {
  296. COptionTracker * pCurOptTracker = pClassTracker->m_listOptions.GetNext(posOption);
  297. CDhcpOption * pCurOption = pCurOptTracker->m_pOption;
  298. if (( pCurOption->QueryId() == pOption->QueryId()) &&
  299. (( pCurOption->IsVendor() && pOption->IsVendor()) ||
  300. ( !pCurOption->IsVendor() && !pOption->IsVendor()))) {
  301. // update this option
  302. CDhcpOptionValue OptValue = pOption->QueryValue();
  303. pCurOption->Update(OptValue);
  304. pCurOptTracker->SetInitialState(OPTION_STATE_ACTIVE);
  305. pCurOptTracker->SetCurrentState(OPTION_STATE_ACTIVE);
  306. break;
  307. } // if
  308. } // while option list
  309. } // while User class list
  310. } // endif vendor class name compre
  311. } // while list of vendor classes
  312. } // while
  313. } // COptionsConfig::UpdateActiveOptions()
  314. void COptionsConfig::FillOptions(LPCTSTR pVendorName, LPCTSTR pUserClassName, CMyListCtrl & ListCtrl)
  315. {
  316. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  317. // look for the requested class and fill in the listbox
  318. // with all options for that class
  319. CString strVendorStandard, strClassStandard, strTargetVendor, strTargetClass;
  320. CString strTypeVendor, strTypeStandard;
  321. strVendorStandard.LoadString(IDS_INFO_NAME_DHCP_DEFAULT);
  322. strClassStandard.LoadString(IDS_USER_STANDARD);
  323. if (strVendorStandard.Compare(pVendorName) != 0)
  324. strTargetVendor = pVendorName;
  325. if (strClassStandard.Compare(pUserClassName) != 0)
  326. strTargetClass = pUserClassName;
  327. POSITION posv = m_listVendorClasses.GetHeadPosition();
  328. while (posv)
  329. {
  330. // find the right vendor
  331. CVendorTracker * pVendorTracker = m_listVendorClasses.GetNext(posv);
  332. if (pVendorTracker->m_strClassName.Compare(strTargetVendor) == 0)
  333. {
  334. POSITION pos = NULL;
  335. pos = pVendorTracker->m_listUserClasses.GetHeadPosition();
  336. while (pos)
  337. {
  338. // now find the right user class
  339. CClassTracker * pClassTracker = pVendorTracker->m_listUserClasses.GetNext(pos);
  340. if (pClassTracker->m_strClassName.Compare(strTargetClass) == 0)
  341. {
  342. // this is the class, add all of the options to the listbox
  343. CString strDisplay, strType, strComment;
  344. POSITION posOption = NULL;
  345. posOption = pClassTracker->m_listOptions.GetHeadPosition();
  346. while (posOption)
  347. {
  348. COptionTracker * pOptionTracker = pClassTracker->m_listOptions.GetNext(posOption);
  349. pOptionTracker->m_pOption->QueryDisplayName(strDisplay);
  350. strComment = pOptionTracker->m_pOption->QueryComment();
  351. strType = pOptionTracker->m_pOption->IsVendor() ? strTypeVendor : strTypeStandard;
  352. int nIndex = ListCtrl.AddItem(strDisplay, strComment, LISTVIEWEX_NOT_CHECKED);
  353. ListCtrl.SetItemData(nIndex, (LPARAM) pOptionTracker);
  354. if (pOptionTracker->GetCurrentState() == OPTION_STATE_ACTIVE)
  355. ListCtrl.CheckItem(nIndex);
  356. }
  357. break;
  358. }
  359. } // while
  360. } // if
  361. } // while
  362. // Finally, Set the column widths so that all items are visible.
  363. // Set the default column widths to the width of the widest column
  364. int aColWidth[ MAX_COLUMNS];
  365. int nRow, nCol;
  366. CString strTemp;
  367. ZeroMemory(aColWidth, MAX_COLUMNS * sizeof(int));
  368. CopyMemory(aColWidth, &COLUMN_WIDTHS, sizeof(MAX_COLUMNS * sizeof(int)));
  369. // for each item, loop through each column and calculate the correct width
  370. for (nRow = 0; nRow < ListCtrl.GetItemCount(); nRow++)
  371. {
  372. for (nCol = 0; nCol < MAX_COLUMNS; nCol++)
  373. {
  374. strTemp = ListCtrl.GetItemText(nRow, nCol);
  375. if (aColWidth[nCol] < ListCtrl.GetStringWidth(strTemp))
  376. aColWidth[nCol] = ListCtrl.GetStringWidth(strTemp);
  377. }
  378. }
  379. // now update the column widths based on what we calculated
  380. for (nCol = 0; nCol < MAX_COLUMNS; nCol++)
  381. {
  382. // GetStringWidth doesn't seem to report the right thing,
  383. // so we have to add a fudge factor of 15.... oh well.
  384. if (aColWidth[nCol] > 0)
  385. ListCtrl.SetColumnWidth(nCol, aColWidth[nCol] + 15);
  386. }
  387. } // COptionsConfig::FillOptions()
  388. /////////////////////////////////////////////////////////////////////////////
  389. // COptionsCfgBasic property page
  390. IMPLEMENT_DYNCREATE(COptionsCfgPropPage, CPropertyPageBase)
  391. COptionsCfgPropPage::COptionsCfgPropPage() :
  392. CPropertyPageBase(COptionsCfgPropPage::IDD),
  393. m_bInitialized(FALSE)
  394. {
  395. LoadBitmaps();
  396. m_helpMap.BuildMap(DhcpGetHelpMap(COptionsCfgPropPage::IDD));
  397. }
  398. COptionsCfgPropPage::COptionsCfgPropPage(UINT nIDTemplate, UINT nIDCaption) :
  399. CPropertyPageBase(nIDTemplate, nIDCaption),
  400. m_bInitialized(FALSE)
  401. {
  402. //{{AFX_DATA_INIT(COptionsCfgPropPage)
  403. //}}AFX_DATA_INIT
  404. LoadBitmaps();
  405. m_helpMap.BuildMap(DhcpGetHelpMap(COptionsCfgPropPage::IDD));
  406. }
  407. COptionsCfgPropPage::~COptionsCfgPropPage()
  408. {
  409. }
  410. void
  411. COptionsCfgPropPage::LoadBitmaps()
  412. {
  413. }
  414. void COptionsCfgPropPage::DoDataExchange(CDataExchange* pDX)
  415. {
  416. CPropertyPageBase::DoDataExchange(pDX);
  417. //{{AFX_DATA_MAP(COptionsCfgPropPage)
  418. DDX_Control(pDX, IDC_LIST_OPTIONS, m_listctrlOptions);
  419. //}}AFX_DATA_MAP
  420. }
  421. BEGIN_MESSAGE_MAP(COptionsCfgPropPage, CPropertyPageBase)
  422. //{{AFX_MSG_MAP(COptionsCfgPropPage)
  423. ON_WM_DESTROY()
  424. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_OPTIONS, OnItemchangedListOptions)
  425. //}}AFX_MSG_MAP
  426. ON_MESSAGE(WM_SELECTOPTION, OnSelectOption)
  427. // Binary array controls
  428. ON_EN_CHANGE(IDC_EDIT_VALUE, OnChangeEditValue)
  429. ON_BN_CLICKED(IDC_BUTTON_VALUE_UP, OnButtonValueUp)
  430. ON_BN_CLICKED(IDC_BUTTON_VALUE_DOWN, OnButtonValueDown)
  431. ON_BN_CLICKED(IDC_BUTTON_VALUE_ADD, OnButtonValueAdd)
  432. ON_BN_CLICKED(IDC_BUTTON_VALUE_DELETE, OnButtonValueDelete)
  433. ON_BN_CLICKED(IDC_RADIO_DECIMAL, OnClickedRadioDecimal)
  434. ON_BN_CLICKED(IDC_RADIO_HEX, OnClickedRadioHex)
  435. ON_LBN_SELCHANGE(IDC_LIST_VALUES, OnSelchangeListValues)
  436. // Byte, WORD and Long edit control
  437. ON_EN_CHANGE(IDC_EDIT_DWORD, OnChangeEditDword)
  438. // string edit control
  439. ON_EN_CHANGE(IDC_EDIT_STRING_VALUE, OnChangeEditString)
  440. // IP Address control
  441. ON_EN_CHANGE(IDC_IPADDR_ADDRESS, OnChangeIpAddress)
  442. // IP Address array controls
  443. ON_EN_CHANGE(IDC_EDIT_SERVER_NAME, OnChangeEditServerName)
  444. ON_EN_CHANGE(IDC_IPADDR_SERVER_ADDRESS, OnChangeIpAddressArray)
  445. ON_BN_CLICKED(IDC_BUTTON_RESOLVE, OnButtonResolve)
  446. ON_BN_CLICKED(IDC_BUTTON_IPADDR_UP, OnButtonIpAddrUp)
  447. ON_BN_CLICKED(IDC_BUTTON_IPADDR_DOWN, OnButtonIpAddrDown)
  448. ON_BN_CLICKED(IDC_BUTTON_IPADDR_ADD, OnButtonIpAddrAdd)
  449. ON_BN_CLICKED(IDC_BUTTON_IPADDR_DELETE, OnButtonIpAddrDelete)
  450. ON_LBN_SELCHANGE(IDC_LIST_IP_ADDRS, OnSelchangeListIpAddrs)
  451. // binary and encapsulated data
  452. ON_EN_CHANGE(IDC_VALUEDATA, OnChangeValueData)
  453. // route array controls
  454. ON_BN_CLICKED(IDC_BUTTON_ROUTE_ADD, OnButtonAddRoute)
  455. ON_BN_CLICKED(IDC_BUTTON_ROUTE_DEL, OnButtonDelRoute)
  456. // string array controls
  457. ON_EN_CHANGE(IDC_EDIT_STRING, OnChangeStringArrayValue)
  458. ON_LBN_SELCHANGE(IDC_LIST_STRING_ARRAY, OnSelChangeStringArrayList)
  459. ON_BN_CLICKED(IDC_BUTTON_STRING_ARRAY_ADD, OnButtonStringArrayAdd)
  460. ON_BN_CLICKED(IDC_BUTTON_STRING_ARRAY_REMOVE, OnButtonStringArrayRemove)
  461. ON_BN_CLICKED(IDC_BUTTON_STRING_ARRAY_UP, OnButtonStringArrayUp)
  462. ON_BN_CLICKED(IDC_BUTTON_STRING_ARRAY_DOWN, OnButtonStringArrayDown)
  463. END_MESSAGE_MAP()
  464. /////////////////////////////////////////////////////////////////////////////
  465. // COptionsCfgPropPage message handlers
  466. afx_msg long COptionsCfgPropPage::OnSelectOption(UINT wParam, LONG lParam)
  467. {
  468. COptionsConfig * pOptionsConfig = (COptionsConfig *) GetHolder();
  469. if (wParam != NULL)
  470. {
  471. CDhcpOptionItem * pOptItem = (CDhcpOptionItem *) ULongToPtr(wParam);
  472. HWND hWnd = NULL;
  473. pOptionsConfig->m_strStartVendor = pOptItem->GetVendor();
  474. pOptionsConfig->m_strStartClass = pOptItem->GetClassName();
  475. pOptionsConfig->m_dhcpStartId = pOptItem->GetOptionId();
  476. if ( (!pOptionsConfig->m_strStartVendor.IsEmpty() ||
  477. !pOptionsConfig->m_strStartClass.IsEmpty()) &&
  478. GetWindowLongPtr(GetSafeHwnd(), GWLP_ID) != IDP_OPTION_ADVANCED)
  479. {
  480. // we're on the basic page, need to switch to advanced
  481. ::PostMessage(pOptionsConfig->GetSheetWindow(), PSM_SETCURSEL, (WPARAM)1, NULL);
  482. hWnd = pOptionsConfig->m_pageAdvanced.GetSafeHwnd();
  483. ::PostMessage(hWnd, WM_SELECTCLASSES, (WPARAM) &pOptionsConfig->m_strStartVendor, (LPARAM) &pOptionsConfig->m_strStartClass);
  484. }
  485. else
  486. if ( (pOptionsConfig->m_strStartVendor.IsEmpty() &&
  487. pOptionsConfig->m_strStartClass.IsEmpty()) &&
  488. GetWindowLongPtr(GetSafeHwnd(), GWLP_ID) != IDP_OPTION_BASIC)
  489. {
  490. // we're on the advanced page, need to switch to basic
  491. ::PostMessage(pOptionsConfig->GetSheetWindow(), PSM_SETCURSEL, (WPARAM)0, NULL);
  492. hWnd = pOptionsConfig->m_pageGeneral.GetSafeHwnd();
  493. }
  494. ::PostMessage(hWnd, WM_SELECTOPTION, 0, 0);
  495. return 0;
  496. }
  497. for (int i = 0; i < m_listctrlOptions.GetItemCount(); i++)
  498. {
  499. COptionTracker * pCurOptTracker =
  500. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(i));
  501. if (pCurOptTracker->m_pOption->QueryId() == pOptionsConfig->m_dhcpStartId)
  502. {
  503. BOOL bDirty = IsDirty();
  504. m_listctrlOptions.SelectItem(i);
  505. m_listctrlOptions.EnsureVisible(i, FALSE);
  506. SetDirty(bDirty);
  507. break;
  508. }
  509. }
  510. // reset this variable since we don't need it anymore
  511. pOptionsConfig->m_dhcpStartId = -1;
  512. return 0;
  513. }
  514. /*---------------------------------------------------------------------------
  515. Handlers for the IP Array controls
  516. ---------------------------------------------------------------------------*/
  517. void COptionsCfgPropPage::OnButtonIpAddrAdd()
  518. {
  519. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  520. CWndIpAddress * pIpAddr = reinterpret_cast<CWndIpAddress *>(GetDlgItem(IDC_IPADDR_SERVER_ADDRESS));
  521. DWORD dwIpAddress;
  522. pIpAddr->GetAddress(&dwIpAddress);
  523. if (dwIpAddress)
  524. {
  525. int nSelectedItem = m_listctrlOptions.GetSelectedItem();
  526. // make sure that sometime is selected
  527. Assert(nSelectedItem > -1);
  528. if (nSelectedItem > -1)
  529. {
  530. CListBox * pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_IP_ADDRS));
  531. CEdit * pServerName = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_SERVER_NAME));
  532. COptionTracker * pOptTracker =
  533. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedItem));
  534. // fill in the information in the option struct
  535. CDhcpOption * pOption = pOptTracker->m_pOption;
  536. CDhcpOptionValue & optValue = pOption->QueryValue();
  537. // check to see if we need to grow the array or not
  538. int nOldUpperBound = optValue.QueryUpperBound();
  539. if ((nOldUpperBound == 1) &&
  540. (optValue.QueryIpAddr() == 0))
  541. {
  542. // this array is empty. Don't need to grow it
  543. nOldUpperBound -= 1;
  544. }
  545. else
  546. {
  547. // Set that the array is growing by 1
  548. optValue.SetUpperBound(nOldUpperBound + 1);
  549. }
  550. optValue.SetIpAddr((DHCP_IP_ADDRESS) dwIpAddress, nOldUpperBound);
  551. pOptTracker->SetDirty(TRUE);
  552. // add to the list box
  553. CString strAddress;
  554. ::UtilCvtIpAddrToWstr(dwIpAddress, &strAddress);
  555. pListBox->AddString(strAddress);
  556. // clear the server edit field and ip address
  557. pServerName->SetWindowText(_T(""));
  558. pIpAddr->ClearAddress();
  559. pIpAddr->SetFocusField(0);
  560. // finally, mark the page as dirty
  561. SetDirty(TRUE);
  562. }
  563. }
  564. else
  565. {
  566. ::DhcpMessageBox(IDS_ERR_DLL_INVALID_ADDRESS);
  567. }
  568. }
  569. void COptionsCfgPropPage::OnButtonIpAddrDelete()
  570. {
  571. int nSelectedOption = m_listctrlOptions.GetSelectedItem();
  572. CEdit * pServerName = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_SERVER_NAME));
  573. CWndIpAddress * pIpAddr = reinterpret_cast<CWndIpAddress *>(GetDlgItem(IDC_IPADDR_SERVER_ADDRESS));
  574. CListBox * pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_IP_ADDRS));
  575. DWORD dwIpAddress;
  576. CString strIpAddress;
  577. int nSelectedIndex = pListBox->GetCurSel();
  578. // get the currently selected item
  579. pListBox->GetText(nSelectedIndex, strIpAddress);
  580. dwIpAddress = UtilCvtWstrToIpAddr(strIpAddress);
  581. // remove from the option
  582. COptionTracker * pOptTracker =
  583. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedOption));
  584. // pOptTracker can be null when the context moves to another option.
  585. // However, this is not disabled, so the user can still try to delete
  586. // an IP since it is active.
  587. //
  588. // Add a null check
  589. if (0 != pOptTracker ) {
  590. // fill in the information in the option struct
  591. CDhcpOption * pOption = pOptTracker->m_pOption;
  592. CDhcpOptionValue & optValue = pOption->QueryValue();
  593. // the listbox should match our array, so we'll remove the same index
  594. optValue.RemoveIpAddr(nSelectedIndex);
  595. optValue.SetUpperBound(optValue.QueryUpperBound() - 1);
  596. // remove from list box
  597. pListBox->DeleteString(nSelectedIndex);
  598. pIpAddr->SetAddress(dwIpAddress);
  599. pServerName->SetWindowText(_T(""));
  600. // mark the option and the page as dirty
  601. pOptTracker->SetDirty(TRUE);
  602. SetDirty(TRUE);
  603. HandleActivationIpArray();
  604. } // if
  605. } // COptionsCfgPropPage::OnButtonIpAddrDelete()
  606. void COptionsCfgPropPage::OnSelchangeListIpAddrs()
  607. {
  608. HandleActivationIpArray();
  609. }
  610. void COptionsCfgPropPage::OnChangeIpAddressArray()
  611. {
  612. HandleActivationIpArray();
  613. }
  614. void COptionsCfgPropPage::OnButtonResolve()
  615. {
  616. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  617. CEdit * pServerName = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_SERVER_NAME));
  618. CString strServer;
  619. DHCP_IP_ADDRESS dhipa = 0;
  620. DWORD err = 0;
  621. pServerName->GetWindowText(strServer);
  622. //
  623. // See what type of name it is.
  624. //
  625. switch (UtilCategorizeName(strServer))
  626. {
  627. case HNM_TYPE_IP:
  628. dhipa = ::UtilCvtWstrToIpAddr( strServer ) ;
  629. break ;
  630. case HNM_TYPE_NB:
  631. case HNM_TYPE_DNS:
  632. err = ::UtilGetHostAddress( strServer, & dhipa ) ;
  633. if (!err)
  634. UtilCvtIpAddrToWstr(dhipa, &strServer);
  635. break ;
  636. default:
  637. err = IDS_ERR_BAD_HOST_NAME ;
  638. break ;
  639. }
  640. if (err)
  641. {
  642. ::DhcpMessageBox(err);
  643. }
  644. else
  645. {
  646. CWndIpAddress * pIpAddr = reinterpret_cast<CWndIpAddress *>(GetDlgItem(IDC_IPADDR_SERVER_ADDRESS));
  647. pIpAddr->SetAddress(dhipa);
  648. }
  649. }
  650. void COptionsCfgPropPage::OnChangeEditServerName()
  651. {
  652. HandleActivationIpArray();
  653. }
  654. void COptionsCfgPropPage::OnButtonIpAddrDown()
  655. {
  656. CButton * pIpAddrDown =
  657. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_DOWN));
  658. CButton * pIpAddrUp =
  659. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_UP));
  660. MoveValue(FALSE, FALSE);
  661. if (pIpAddrDown->IsWindowEnabled())
  662. pIpAddrDown->SetFocus();
  663. else
  664. pIpAddrUp->SetFocus();
  665. }
  666. void COptionsCfgPropPage::OnButtonIpAddrUp()
  667. {
  668. CButton * pIpAddrDown =
  669. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_DOWN));
  670. CButton * pIpAddrUp =
  671. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_UP));
  672. MoveValue(FALSE, TRUE);
  673. if (pIpAddrUp->IsWindowEnabled())
  674. pIpAddrUp->SetFocus();
  675. else
  676. pIpAddrDown->SetFocus();
  677. }
  678. /*---------------------------------------------------------------------------
  679. Handlers for the number array controls
  680. ---------------------------------------------------------------------------*/
  681. void COptionsCfgPropPage::OnButtonValueAdd()
  682. {
  683. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  684. COptionTracker * pOptTracker =
  685. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  686. CEdit * pValue = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_VALUE));
  687. CListBox * pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_VALUES));
  688. // Get the OptionValue object
  689. CDhcpOption * pOption = pOptTracker->m_pOption;
  690. CDhcpOptionValue & optValue = pOption->QueryValue();
  691. DWORD dwValue;
  692. DWORD_DWORD dwdwValue;
  693. DWORD dwMask = 0xFFFFFFFF ;
  694. switch ( optValue.QueryDataType())
  695. {
  696. case DhcpBinaryDataOption :
  697. case DhcpByteOption:
  698. dwMask = 0xFF ;
  699. break ;
  700. case DhcpWordOption:
  701. dwMask = 0xFFFF ;
  702. break ;
  703. } // switch
  704. if (optValue.QueryDataType() == DhcpDWordDWordOption)
  705. {
  706. CString strValue;
  707. pValue->GetWindowText(strValue);
  708. UtilConvertStringToDwordDword(strValue, &dwdwValue);
  709. }
  710. else
  711. {
  712. if (!FGetCtrlDWordValue(pValue->GetSafeHwnd(), &dwValue, 0, dwMask))
  713. return;
  714. }
  715. DWORD err = 0 ;
  716. CATCH_MEM_EXCEPTION
  717. {
  718. // Set that the array is growing by 1
  719. int nOldUpperBound = optValue.QueryUpperBound();
  720. optValue.SetUpperBound(nOldUpperBound + 1);
  721. // now insert the new item as the last item in the array
  722. (optValue.QueryDataType() == DhcpDWordDWordOption)
  723. ? optValue.SetDwordDword(dwdwValue, nOldUpperBound)
  724. : optValue.SetNumber(dwValue, nOldUpperBound);
  725. }
  726. END_MEM_EXCEPTION(err)
  727. if ( err )
  728. {
  729. ::DhcpMessageBox( err ) ;
  730. }
  731. else
  732. {
  733. pOptTracker->SetDirty(TRUE);
  734. SetDirty(TRUE);
  735. }
  736. //
  737. // update controls. clear the edit control
  738. //
  739. pValue->SetWindowText(_T(""));
  740. pValue->SetFocus();
  741. FillDataEntry(pOption);
  742. HandleActivationValueArray();
  743. } // COptionsCfgPropPage::OnButtonValueAdd()
  744. void COptionsCfgPropPage::OnButtonValueDelete()
  745. {
  746. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  747. COptionTracker * pOptTracker =
  748. reinterpret_cast<COptionTracker *>( m_listctrlOptions.GetItemData( nSelectedIndex ));
  749. CEdit * pValue = reinterpret_cast<CEdit *>( GetDlgItem( IDC_EDIT_VALUE ));
  750. CListBox * pListBox =
  751. reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_VALUES ));
  752. // Get the OptionValue object
  753. CDhcpOption * pOption = pOptTracker->m_pOption;
  754. CDhcpOptionValue & optValue = pOption->QueryValue();
  755. CString strValue;
  756. int nListBoxIndex = pListBox->GetCurSel();
  757. // get the currently selected item
  758. pListBox->GetText(nListBoxIndex, strValue);
  759. //if (!FGetCtrlDWordValue(pValue->GetSafeHwnd(), &dwValue, 0, dwMask))
  760. // return;
  761. // the listbox should match our array, so we'll remove the same index
  762. (optValue.QueryDataType() == DhcpDWordDWordOption) ?
  763. optValue.RemoveDwordDword(nListBoxIndex) : optValue.RemoveNumber(nListBoxIndex);
  764. optValue.SetUpperBound(optValue.QueryUpperBound() - 1);
  765. // remove from list box
  766. pListBox->DeleteString( nListBoxIndex );
  767. nListBoxIndex--;
  768. if ( nListBoxIndex < 0 ) {
  769. nListBoxIndex = 0;
  770. }
  771. pListBox->SetCurSel( nListBoxIndex );
  772. pValue->SetWindowText(strValue);
  773. // mark the option and the page as dirty
  774. pOptTracker->SetDirty(TRUE);
  775. SetDirty(TRUE);
  776. HandleActivationValueArray();
  777. }
  778. void COptionsCfgPropPage::OnButtonValueDown()
  779. {
  780. CButton * pValueDown =
  781. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_DOWN));
  782. CButton * pValueUp =
  783. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_UP));
  784. MoveValue(TRUE, FALSE);
  785. if (pValueDown->IsWindowEnabled())
  786. pValueDown->SetFocus();
  787. else
  788. pValueUp->SetFocus();
  789. }
  790. void COptionsCfgPropPage::OnButtonValueUp()
  791. {
  792. CButton * pValueDown =
  793. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_DOWN));
  794. CButton * pValueUp =
  795. reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_UP));
  796. MoveValue(TRUE, TRUE);
  797. if (pValueUp->IsWindowEnabled())
  798. pValueUp->SetFocus();
  799. else
  800. pValueDown->SetFocus();
  801. }
  802. void COptionsCfgPropPage::MoveValue(BOOL bValues, BOOL bUp)
  803. {
  804. int nSelectedOption = m_listctrlOptions.GetSelectedItem();
  805. // Get the option that describes this
  806. COptionTracker * pOptTracker =
  807. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedOption));
  808. if ( 0 == pOptTracker ) {
  809. return;
  810. }
  811. CDhcpOption * pOption = pOptTracker->m_pOption;
  812. if ( 0 == pOption ) {
  813. return;
  814. }
  815. CDhcpOptionValue & optValue = pOption->QueryValue();
  816. // Get the correct listbox
  817. CListBox * pListBox;
  818. if (bValues)
  819. {
  820. // this is for values
  821. pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_VALUES));
  822. }
  823. else
  824. {
  825. // this is for IpAddrs
  826. pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_IP_ADDRS));
  827. }
  828. if ( 0 == pListBox ) {
  829. return;
  830. }
  831. // now get which item is selected in the listbox
  832. int cFocus = pListBox->GetCurSel();
  833. // make sure it's valid for this operation
  834. if ( (bUp && cFocus <= 0) ||
  835. (!bUp && cFocus >= pListBox->GetCount()) )
  836. {
  837. return;
  838. }
  839. DWORD dwValue;
  840. DWORD_DWORD dwdwValue;
  841. DWORD err = 0 ;
  842. // move the value up/down
  843. CATCH_MEM_EXCEPTION
  844. {
  845. if (optValue.QueryDataType() == DhcpDWordDWordOption)
  846. {
  847. DWORD_DWORD dwUpValue;
  848. DWORD_DWORD dwDownValue;
  849. if (bUp)
  850. {
  851. dwdwValue = dwUpValue = optValue.QueryDwordDword(cFocus);
  852. dwDownValue = optValue.QueryDwordDword(cFocus - 1);
  853. optValue.SetDwordDword(dwUpValue, cFocus - 1);
  854. optValue.SetDwordDword(dwDownValue, cFocus);
  855. }
  856. else
  857. {
  858. dwdwValue = dwDownValue = optValue.QueryDwordDword(cFocus);
  859. dwUpValue = optValue.QueryDwordDword(cFocus + 1);
  860. optValue.SetDwordDword(dwDownValue, cFocus + 1);
  861. optValue.SetDwordDword(dwUpValue, cFocus);
  862. }
  863. }
  864. else
  865. {
  866. DWORD dwUpValue;
  867. DWORD dwDownValue;
  868. if (bUp)
  869. {
  870. dwValue = dwUpValue = optValue.QueryNumber(cFocus);
  871. dwDownValue = optValue.QueryNumber(cFocus - 1);
  872. optValue.SetNumber(dwUpValue, cFocus - 1);
  873. optValue.SetNumber(dwDownValue, cFocus);
  874. }
  875. else
  876. {
  877. dwValue = dwDownValue = optValue.QueryNumber(cFocus);
  878. dwUpValue = optValue.QueryNumber(cFocus + 1);
  879. optValue.SetNumber(dwDownValue, cFocus + 1);
  880. optValue.SetNumber(dwUpValue, cFocus);
  881. }
  882. }
  883. }
  884. END_MEM_EXCEPTION(err)
  885. if ( err )
  886. {
  887. ::DhcpMessageBox( err ) ;
  888. }
  889. else
  890. {
  891. // everything is ok, mark this option and the prop sheet
  892. pOptTracker->SetDirty(TRUE);
  893. SetDirty(TRUE);
  894. }
  895. // update the data.
  896. FillDataEntry(pOption);
  897. // Set the selection correctly
  898. pListBox->SetCurSel( bUp ? cFocus - 1 : cFocus + 1 );
  899. // update the controls
  900. if (bValues)
  901. {
  902. HandleActivationValueArray();
  903. }
  904. else
  905. {
  906. HandleActivationIpArray();
  907. }
  908. } // COptionsCfgPropPage::MoveValue()
  909. void COptionsCfgPropPage::OnChangeEditValue()
  910. {
  911. HandleActivationValueArray();
  912. }
  913. void COptionsCfgPropPage::OnClickedRadioDecimal()
  914. {
  915. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  916. COptionTracker * pOptTracker =
  917. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  918. CDhcpOption * pOption = pOptTracker->m_pOption;
  919. FillDataEntry(pOption);
  920. }
  921. void COptionsCfgPropPage::OnClickedRadioHex()
  922. {
  923. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  924. COptionTracker * pOptTracker =
  925. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  926. CDhcpOption * pOption = pOptTracker->m_pOption;
  927. FillDataEntry(pOption);
  928. }
  929. void COptionsCfgPropPage::OnSelchangeListValues()
  930. {
  931. HandleActivationValueArray();
  932. }
  933. /*---------------------------------------------------------------------------
  934. Handlers for the binary and encapsulated data
  935. ---------------------------------------------------------------------------*/
  936. void COptionsCfgPropPage::OnChangeValueData()
  937. {
  938. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  939. COptionTracker * pOptTracker =
  940. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  941. CEdit * pValue = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_VALUE));
  942. CListBox * pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_VALUES));
  943. // Get the OptionValue object
  944. CDhcpOption * pOption = pOptTracker->m_pOption;
  945. CDhcpOptionValue & optValue = pOption->QueryValue();
  946. // get the info from the control
  947. HEXEDITDATA * pHexEditData = (HEXEDITDATA *) GetWindowLongPtr(GetDlgItem(IDC_VALUEDATA)->GetSafeHwnd(), GWLP_USERDATA);
  948. DWORD err = 0;
  949. CATCH_MEM_EXCEPTION
  950. {
  951. // size we don't know what changed, we just have to copy all of the data
  952. optValue.RemoveAll();
  953. for (int i = 0; i < pHexEditData->cbBuffer; i++)
  954. {
  955. DWORD dwValue = (BYTE) pHexEditData->pBuffer[i];
  956. optValue.SetNumber(dwValue, i);
  957. }
  958. }
  959. END_MEM_EXCEPTION(err)
  960. // mark the option and the page as dirty
  961. pOptTracker->SetDirty(TRUE);
  962. SetDirty(TRUE);
  963. }
  964. /*---------------------------------------------------------------------------
  965. Handlers for the single number entry controls
  966. ---------------------------------------------------------------------------*/
  967. void COptionsCfgPropPage::OnChangeEditDword()
  968. {
  969. HandleValueEdit();
  970. }
  971. /*---------------------------------------------------------------------------
  972. Handlers for the single IP Address entry controls
  973. ---------------------------------------------------------------------------*/
  974. void COptionsCfgPropPage::OnChangeIpAddress()
  975. {
  976. HandleValueEdit();
  977. }
  978. /*---------------------------------------------------------------------------
  979. Handlers for the string entry controls
  980. ---------------------------------------------------------------------------*/
  981. void COptionsCfgPropPage::OnChangeEditString()
  982. {
  983. HandleValueEdit();
  984. }
  985. /////////////////////////////////////////////////////////////////////////////
  986. // CAddRoute dialog
  987. CAddRoute::CAddRoute( CWnd *pParent)
  988. : CBaseDialog( CAddRoute::IDD, pParent )
  989. {
  990. m_ipaDest.ClearAddress();
  991. m_ipaMask.ClearAddress();
  992. m_ipaRouter.ClearAddress();
  993. m_bChange = FALSE;
  994. }
  995. void CAddRoute::DoDataExchange(CDataExchange* pDX)
  996. {
  997. CBaseDialog::DoDataExchange(pDX);
  998. //{{AFX_DATA_MAP(CAddRoute)
  999. //}}AFX_DATA_MAP
  1000. DDX_Control(pDX, IDC_IPADDR_ADDRESS, m_ipaDest);
  1001. DDX_Control(pDX, IDC_IPADDR_ADDRESS2, m_ipaMask);
  1002. DDX_Control(pDX, IDC_IPADDR_ADDRESS3, m_ipaRouter);
  1003. }
  1004. BEGIN_MESSAGE_MAP(CAddRoute, CBaseDialog)
  1005. //{{AFX_MSG_MAP(CAddRoute)
  1006. //}}AFX_MSG_MAP
  1007. END_MESSAGE_MAP()
  1008. /////////////////////////////////////////////////////////////////////////////
  1009. // CAddReservation message handlers
  1010. BOOL CAddRoute::OnInitDialog()
  1011. {
  1012. CBaseDialog::OnInitDialog();
  1013. // set focus on the destination..
  1014. CWnd *pWnd = GetDlgItem(IDC_IPADDR_ADDRESS);
  1015. if( NULL != pWnd )
  1016. {
  1017. pWnd->SetFocus();
  1018. return FALSE;
  1019. }
  1020. return TRUE; // return TRUE unless you set the focus to a control
  1021. // EXCEPTION: OCX Property Pages should return FALSE
  1022. }
  1023. void CAddRoute::OnOK()
  1024. {
  1025. DWORD err = 0;
  1026. UpdateData();
  1027. m_ipaDest.GetAddress( &Dest );
  1028. m_ipaMask.GetAddress( &Mask );
  1029. m_ipaRouter.GetAddress( &Router );
  1030. // validate the ip addresses
  1031. if( 0 == Router || (0 != Mask && 0 == Dest) ||
  1032. 0 != ((~Mask) & Dest) ||
  1033. (0 != ((~Mask) & ((~Mask)+1)) ) )
  1034. {
  1035. ::DhcpMessageBox( IDS_ERR_INVALID_ROUTE_ENTRY );
  1036. }
  1037. else
  1038. {
  1039. m_bChange = TRUE;
  1040. CBaseDialog::OnOK();
  1041. }
  1042. //CBaseDialog::OnOK();
  1043. }
  1044. /*--------------------------------------------------------------------------
  1045. Handlers for String Array Editor
  1046. ---------------------------------------------------------------------------*/
  1047. void COptionsCfgPropPage::OnSelChangeStringArrayList()
  1048. {
  1049. HandleActivationStringArray();
  1050. } // COptionsCfgPropPage::OnSelChangeStringArrayList()
  1051. void COptionsCfgPropPage::OnChangeStringArrayValue()
  1052. {
  1053. // Get the string edit box control
  1054. CEdit *pEdit = reinterpret_cast<CEdit *>( GetDlgItem( IDC_EDIT_STRING ));
  1055. CString str;
  1056. pEdit->GetWindowText( str );
  1057. if ( !str.IsEmpty())
  1058. {
  1059. CButton *pAdd = reinterpret_cast<CButton *>( GetDlgItem( IDC_BUTTON_STRING_ARRAY_ADD ));
  1060. pAdd->EnableWindow( TRUE );
  1061. }
  1062. HandleActivationStringArray();
  1063. } // COptionsCfgPropPage::OnChangeStringArrayValue()
  1064. void COptionsCfgPropPage::OnButtonStringArrayAdd()
  1065. {
  1066. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1067. COptionTracker * pOptTracker =
  1068. reinterpret_cast<COptionTracker *>( m_listctrlOptions.GetItemData( nSelectedIndex ));
  1069. // Get the OptionValue object
  1070. CDhcpOption * pOption = pOptTracker->m_pOption;
  1071. CDhcpOptionValue & optValue = pOption->QueryValue();
  1072. // Get the strings list control
  1073. CListBox *pList = reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_STRING_ARRAY ));
  1074. // Get the string edit box control
  1075. CEdit *pEdit = reinterpret_cast<CEdit *>( GetDlgItem( IDC_EDIT_STRING ));
  1076. CString strValue;
  1077. pEdit->GetWindowText( strValue );
  1078. // Do not add empty strings
  1079. if ( !strValue.IsEmpty())
  1080. {
  1081. pList->InsertString( 0, strValue );
  1082. pList->SetCurSel( 0 );
  1083. pEdit->SetWindowText( L"" );
  1084. } // if
  1085. HandleActivationStringArray();
  1086. // set the focus back to the edit box
  1087. pEdit->SetFocus();
  1088. pOptTracker->SetDirty( TRUE );
  1089. SetDirty( TRUE );
  1090. } // COptionsCfgPropPage::OnButtonStringArrayAdd()
  1091. void COptionsCfgPropPage::OnButtonStringArrayRemove()
  1092. {
  1093. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1094. COptionTracker * pOptTracker =
  1095. reinterpret_cast<COptionTracker *>( m_listctrlOptions.GetItemData( nSelectedIndex ));
  1096. // Get the OptionValue object
  1097. CDhcpOption * pOption = pOptTracker->m_pOption;
  1098. CDhcpOptionValue & optValue = pOption->QueryValue();
  1099. // Get the strings list control
  1100. CListBox *pList = reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_STRING_ARRAY ));
  1101. CEdit *pEdit = reinterpret_cast<CEdit *>( GetDlgItem( IDC_EDIT_STRING ));
  1102. CString str;
  1103. int nItem = pList->GetCurSel();
  1104. pList->GetText( nItem, str );
  1105. pEdit->SetWindowText( str );
  1106. optValue.RemoveString( nItem );
  1107. pList->DeleteString( nItem );
  1108. nItem--;
  1109. if ( nItem < 0 )
  1110. {
  1111. nItem = 0;
  1112. }
  1113. pList->SetCurSel( nItem );
  1114. pList->SetFocus();
  1115. HandleActivationStringArray();
  1116. pOptTracker->SetDirty( TRUE );
  1117. SetDirty( TRUE );
  1118. } // COptionsCfgPropPage::OnButtonStringArrayRemove()
  1119. void COptionsCfgPropPage::OnButtonStringArrayUp()
  1120. {
  1121. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1122. COptionTracker * pOptTracker =
  1123. reinterpret_cast<COptionTracker *>( m_listctrlOptions.GetItemData( nSelectedIndex ));
  1124. // Get the strings list control
  1125. CListBox *pList = reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_STRING_ARRAY ));
  1126. int nItem = pList->GetCurSel();
  1127. CString str;
  1128. if ( nItem > 0 )
  1129. {
  1130. pList->GetText( nItem, str );
  1131. pList->DeleteString( nItem );
  1132. pList->InsertString( nItem - 1, str );
  1133. pList->SetCurSel( nItem - 1 );
  1134. pOptTracker->SetDirty( TRUE );
  1135. SetDirty( TRUE );
  1136. } // if
  1137. HandleActivationStringArray();
  1138. } // COptionsCfgPropPage::OnButtonStringArrayUp()
  1139. void COptionsCfgPropPage::OnButtonStringArrayDown()
  1140. {
  1141. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1142. COptionTracker * pOptTracker =
  1143. reinterpret_cast<COptionTracker *>( m_listctrlOptions.GetItemData( nSelectedIndex ));
  1144. // Get the strings list control
  1145. CListBox *pList = reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_STRING_ARRAY ));
  1146. int nItem = pList->GetCurSel();
  1147. CString str;
  1148. int nCount = pList->GetCount();
  1149. if ( nItem < nCount - 1 )
  1150. {
  1151. pList->GetText( nItem, str );
  1152. pList->DeleteString( nItem );
  1153. if ( nItem < nCount - 1 )
  1154. {
  1155. nItem++;
  1156. }
  1157. pList->InsertString( nItem, str );
  1158. pList->SetCurSel( nItem );
  1159. pOptTracker->SetDirty( TRUE );
  1160. SetDirty( TRUE );
  1161. } // ifs
  1162. HandleActivationStringArray();
  1163. } // COptionsCfgPropPage::OnButtonStringArrayDown()
  1164. /*---------------------------------------------------------------------------
  1165. Handlers for the route add data entry controls
  1166. ---------------------------------------------------------------------------*/
  1167. void COptionsCfgPropPage::OnButtonAddRoute()
  1168. {
  1169. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1170. COptionTracker * pOptTracker =
  1171. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  1172. // Get the OptionValue object
  1173. CDhcpOption * pOption = pOptTracker->m_pOption;
  1174. CDhcpOptionValue & optValue = pOption->QueryValue();
  1175. // get the routes list control
  1176. CListCtrl *pList = reinterpret_cast<CListCtrl *>(
  1177. GetDlgItem( IDC_LIST_OF_ROUTES ) );
  1178. // get the add and remove buttons
  1179. CButton *pAdd = reinterpret_cast<CButton *>(
  1180. GetDlgItem(IDC_BUTTON_ROUTE_ADD) );
  1181. CButton *pRemove = reinterpret_cast<CButton *>(
  1182. GetDlgItem(IDC_BUTTON_ROUTE_DEL) );
  1183. // throw the add route UI
  1184. CAddRoute NewRoute(NULL);
  1185. NewRoute.DoModal();
  1186. if( NewRoute.m_bChange ) {
  1187. CString strDest, strMask, strRouter;
  1188. // obtain the three strings..
  1189. ::UtilCvtIpAddrToWstr(NewRoute.Dest, &strDest);
  1190. ::UtilCvtIpAddrToWstr(NewRoute.Mask, &strMask);
  1191. ::UtilCvtIpAddrToWstr(NewRoute.Router, &strRouter);
  1192. LV_ITEM lvi;
  1193. lvi.mask = LVIF_TEXT;
  1194. lvi.iItem = pList->GetItemCount();
  1195. lvi.iSubItem = 0;
  1196. lvi.pszText = (LPTSTR)(LPCTSTR)strDest;
  1197. lvi.iImage = 0;
  1198. lvi.stateMask = 0;
  1199. int nItem = pList->InsertItem(&lvi);
  1200. pList->SetItemText(nItem, 1, strMask);
  1201. pList->SetItemText(nItem, 2, strRouter);
  1202. // Unselect other items
  1203. for ( int i = 0; i < pList->GetItemCount(); i++ ) {
  1204. pList->SetItemState( i, 0, LVIS_SELECTED );
  1205. }
  1206. // Select this item
  1207. pList->SetItemState( nItem, LVIS_SELECTED, LVIS_SELECTED );
  1208. pOptTracker->SetDirty(TRUE);
  1209. SetDirty(TRUE);
  1210. } // if
  1211. // now walk through the list control and get the values and
  1212. // put them back onto the optValue
  1213. HandleActivationRouteArray( &optValue );
  1214. } // COptionsCfgPropPage::OnButtonAddRoute()
  1215. void COptionsCfgPropPage::OnButtonDelRoute()
  1216. {
  1217. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1218. int nDelItem = 0;
  1219. int nItems;
  1220. COptionTracker * pOptTracker =
  1221. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  1222. // Get the OptionValue object
  1223. CDhcpOption * pOption = pOptTracker->m_pOption;
  1224. CDhcpOptionValue & optValue = pOption->QueryValue();
  1225. // get the routes list control
  1226. CListCtrl *pList = reinterpret_cast<CListCtrl *>
  1227. ( GetDlgItem( IDC_LIST_OF_ROUTES ));
  1228. // get the add and remove buttons
  1229. CButton *pAdd = reinterpret_cast<CButton *>
  1230. ( GetDlgItem( IDC_BUTTON_ROUTE_ADD ));
  1231. CButton *pRemove = reinterpret_cast<CButton *>
  1232. ( GetDlgItem( IDC_BUTTON_ROUTE_DEL ));
  1233. // get the selected column and delete it
  1234. int nItem = pList->GetNextItem(-1, LVNI_SELECTED);
  1235. while( nItem != -1 ) {
  1236. pList->DeleteItem( nItem ) ;
  1237. nDelItem = nItem;
  1238. nItem = pList->GetNextItem(-1, LVNI_SELECTED);
  1239. pOptTracker->SetDirty(TRUE);
  1240. SetDirty(TRUE);
  1241. } // while
  1242. // Select an item
  1243. nItems = pList->GetItemCount();
  1244. if ( nItems > 0 ) {
  1245. if ( nDelItem >= nItems ) {
  1246. nDelItem = nItems - 1;
  1247. }
  1248. pList->SetItemState( nDelItem, LVIS_SELECTED, LVIS_SELECTED );
  1249. } // if
  1250. // now walk through the list control and get the values and
  1251. // put them back onto the optValue
  1252. HandleActivationRouteArray( &optValue );
  1253. } // COptionsCfgPropPage::OnButtonDelRoute()
  1254. BOOL COptionsCfgPropPage::OnInitDialog()
  1255. {
  1256. CPropertyPageBase::OnInitDialog();
  1257. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1258. // set the title
  1259. ((COptionsConfig *) GetHolder())->SetTitle();
  1260. // initialize the list control
  1261. InitListCtrl();
  1262. // initialize the option data
  1263. DWORD dwErr = ((COptionsConfig *) GetHolder())->InitData();
  1264. if (dwErr != ERROR_SUCCESS) {
  1265. // CODEWORK: need to exit gracefull if this happens
  1266. ::DhcpMessageBox(dwErr);
  1267. }
  1268. else {
  1269. // Fill the options for this page type - basic, advanced, custom
  1270. ((COptionsConfig *) GetHolder())->FillOptions(_T(""), _T(""), m_listctrlOptions);
  1271. }
  1272. // Create the type control switcher
  1273. m_cgsTypes.Create(this,IDC_DATA_ENTRY_ANCHOR,cgsPreCreateAll);
  1274. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_NONE, IDD_DATA_ENTRY_NONE, NULL);
  1275. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_DWORD, IDD_DATA_ENTRY_DWORD, NULL);
  1276. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_IPADDRESS, IDD_DATA_ENTRY_IPADDRESS, NULL);
  1277. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_IPADDRESS_ARRAY, IDD_DATA_ENTRY_IPADDRESS_ARRAY, NULL);
  1278. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_STRING, IDD_DATA_ENTRY_STRING, NULL);
  1279. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_BINARY_ARRAY, IDD_DATA_ENTRY_BINARY_ARRAY, NULL);
  1280. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_BINARY, IDD_DATA_ENTRY_BINARY, NULL);
  1281. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_ROUTE_ARRAY, IDD_DATA_ENTRY_ROUTE_ARRAY, NULL);
  1282. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_STRING_ARRAY, IDD_DATA_ENTRY_STRING_ARRAY, NULL);
  1283. m_hexData.SubclassDlgItem(IDC_VALUEDATA, this);
  1284. SwitchDataEntry(-1, -1, 0, TRUE);
  1285. SetDirty(FALSE);
  1286. m_bInitialized = TRUE;
  1287. return TRUE; // return TRUE unless you set the focus to a control
  1288. // EXCEPTION: OCX Property Pages should return FALSE
  1289. } // COptionsCfgPropPage::OnInitDialog()
  1290. void COptionsCfgPropPage::SelectOption(CDhcpOption * pOption)
  1291. {
  1292. for (int i = 0; i < m_listctrlOptions.GetItemCount(); i++)
  1293. {
  1294. COptionTracker * pCurOptTracker =
  1295. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(i));
  1296. if (pOption->QueryId() == pCurOptTracker->m_pOption->QueryId())
  1297. {
  1298. m_listctrlOptions.SelectItem(i);
  1299. m_listctrlOptions.EnsureVisible(i, FALSE);
  1300. }
  1301. }
  1302. }
  1303. void COptionsCfgPropPage::SwitchDataEntry(
  1304. int datatype,
  1305. int optiontype,
  1306. BOOL fRouteArray,
  1307. BOOL bEnable
  1308. )
  1309. {
  1310. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1311. CString strType;
  1312. if( fRouteArray )
  1313. {
  1314. // ignore any other types passed and use route_array type
  1315. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_ROUTE_ARRAY);
  1316. }
  1317. else {
  1318. switch(datatype) {
  1319. case DhcpByteOption:
  1320. case DhcpWordOption:
  1321. case DhcpDWordOption:
  1322. case DhcpDWordDWordOption:
  1323. {
  1324. // build our string for the type of data
  1325. if ( (datatype == DhcpByteOption) ||
  1326. (datatype == DhcpEncapsulatedDataOption) )
  1327. {
  1328. strType.LoadString(IDS_INFO_TYPOPT_BYTE);
  1329. }
  1330. else
  1331. if (datatype == DhcpWordOption)
  1332. {
  1333. strType.LoadString(IDS_INFO_TYPOPT_WORD);
  1334. }
  1335. else
  1336. if (datatype == DhcpDWordOption)
  1337. {
  1338. strType.LoadString(IDS_INFO_TYPOPT_DWORD);
  1339. }
  1340. else
  1341. {
  1342. strType.LoadString(IDS_INFO_TYPOPT_DWDW);
  1343. }
  1344. if (optiontype == DhcpArrayTypeOption)
  1345. {
  1346. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_BINARY_ARRAY);
  1347. CButton * pRadioDecimal =
  1348. reinterpret_cast<CButton *>(GetDlgItem(IDC_RADIO_DECIMAL));
  1349. CButton * pRadioHex =
  1350. reinterpret_cast<CButton *>( GetDlgItem( IDC_RADIO_HEX ));
  1351. if ( !( pRadioHex->GetCheck() ^ pRadioDecimal->GetCheck())) {
  1352. pRadioDecimal->SetCheck( 1 );
  1353. }
  1354. // set some information text
  1355. CString strFrameText;
  1356. strFrameText.LoadString(IDS_DATA_ENTRY_FRAME);
  1357. strFrameText += _T(" ") + strType;
  1358. CWnd * pWnd = GetDlgItem(IDC_STATIC_BINARY_ARRAY_FRAME);
  1359. pWnd->SetWindowText(strFrameText);
  1360. }
  1361. else
  1362. {
  1363. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_DWORD);
  1364. CWnd * pWnd = GetDlgItem(IDC_STATIC_TYPE);
  1365. pWnd->SetWindowText(strType);
  1366. }
  1367. }
  1368. break;
  1369. case DhcpBinaryDataOption:
  1370. case DhcpEncapsulatedDataOption:
  1371. {
  1372. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_BINARY);
  1373. }
  1374. break;
  1375. case DhcpIpAddressOption:
  1376. if (optiontype == DhcpArrayTypeOption)
  1377. {
  1378. strType.LoadString(IDS_INFO_TYPOPT_BYTE);
  1379. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_IPADDRESS_ARRAY);
  1380. CButton * pRadioDecimal =
  1381. reinterpret_cast<CButton *>(GetDlgItem(IDC_RADIO_DECIMAL));
  1382. pRadioDecimal->SetCheck(1);
  1383. // set some information text
  1384. CString strFrameText;
  1385. strFrameText.LoadString(IDS_DATA_ENTRY_FRAME);
  1386. strFrameText += _T(" ") + strType;
  1387. CWnd * pWnd = GetDlgItem(IDC_STATIC_BINARY_ARRAY_FRAME);
  1388. pWnd->SetWindowText(strFrameText);
  1389. }
  1390. else
  1391. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_IPADDRESS);
  1392. break;
  1393. case DhcpStringDataOption:
  1394. if (optiontype == DhcpArrayTypeOption)
  1395. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_STRING_ARRAY);
  1396. else
  1397. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_STRING);
  1398. break;
  1399. default:
  1400. m_cgsTypes.ShowGroup(IDC_DATA_ENTRY_NONE);
  1401. break;
  1402. } // switch
  1403. } // else
  1404. // enable/disable the current group
  1405. m_cgsTypes.EnableGroup(-1, bEnable);
  1406. } // COptionsCfgPropPage::SwitchDataEntry()
  1407. const int ROUTE_LIST_COL_WIDTHS[3] = {
  1408. 100, 100, 100
  1409. };
  1410. const int ROUTE_LIST_COL_HEADERS[3] = {
  1411. IDS_ROUTE_LIST_COL_DEST,
  1412. IDS_ROUTE_LIST_COL_MASK,
  1413. IDS_ROUTE_LIST_COL_ROUTER
  1414. };
  1415. void COptionsCfgPropPage::FillDataEntry(CDhcpOption * pOption)
  1416. {
  1417. CDhcpOptionValue & optValue = pOption->QueryValue();
  1418. int datatype = pOption->QueryDataType();
  1419. int optiontype = pOption->QueryOptType();
  1420. BOOL fRouteArray = ( !pOption->IsClassOption() &&
  1421. (DHCP_OPTION_ID_CSR == pOption->QueryId()) &&
  1422. optiontype == DhcpUnaryElementTypeOption &&
  1423. datatype == DhcpBinaryDataOption
  1424. );
  1425. CButton * pRadioHex =
  1426. reinterpret_cast<CButton *>(GetDlgItem(IDC_RADIO_HEX));
  1427. BOOL bUseHex = pRadioHex->GetCheck();
  1428. if( fRouteArray )
  1429. {
  1430. const CByteArray * pbaData = optValue.QueryBinaryArray();
  1431. int nDataSize = (int)pbaData->GetSize();
  1432. LPBYTE pData = (LPBYTE) pbaData->GetData();
  1433. // initialize the list control view with data
  1434. CListCtrl *pList =
  1435. reinterpret_cast<CListCtrl *>(GetDlgItem(IDC_LIST_OF_ROUTES));
  1436. Assert(pList);
  1437. pList->DeleteAllItems();
  1438. pList->SetExtendedStyle(LVS_EX_FULLROWSELECT);
  1439. pList->DeleteColumn(2);
  1440. pList->DeleteColumn(1);
  1441. pList->DeleteColumn(0);
  1442. LV_COLUMN lvc;
  1443. CString strColHeader;
  1444. for( int i = 0; i < 3; i ++ )
  1445. {
  1446. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH ;
  1447. lvc.iSubItem = i;
  1448. lvc.fmt = LVCFMT_LEFT;
  1449. lvc.cx = ROUTE_LIST_COL_WIDTHS[i];
  1450. strColHeader.LoadString(ROUTE_LIST_COL_HEADERS[i]);
  1451. lvc.pszText = (LPTSTR)(LPCTSTR)strColHeader;
  1452. pList->InsertColumn( i, &lvc );
  1453. } // for
  1454. // convert pData to list of ip addresses as per RFC
  1455. while( nDataSize > sizeof(DWORD) )
  1456. {
  1457. // first 1 byte contains the # of bits in subnetmask
  1458. nDataSize --;
  1459. BYTE nBitsMask = *pData ++;
  1460. DWORD Mask = (~0);
  1461. if( nBitsMask < 32 ) Mask <<= (32-nBitsMask);
  1462. // based on the # of bits, the next few bytes contain
  1463. // the subnet address for the 1-bits of subnet mask
  1464. int nBytesDest = (nBitsMask+7)/8;
  1465. if( nBytesDest > 4 ) nBytesDest = 4;
  1466. DWORD Dest = 0;
  1467. memcpy( &Dest, pData, nBytesDest );
  1468. pData += nBytesDest;
  1469. nDataSize -= nBytesDest;
  1470. // subnet address is obviously in network order.
  1471. Dest = ntohl(Dest);
  1472. // now the four bytes would be the router address
  1473. DWORD Router = 0;
  1474. if( nDataSize < sizeof(DWORD) )
  1475. {
  1476. Assert( FALSE ); break;
  1477. }
  1478. memcpy(&Router, pData, sizeof(DWORD));
  1479. Router = ntohl( Router );
  1480. pData += sizeof(DWORD);
  1481. nDataSize -= sizeof(DWORD);
  1482. // now fill the list box..
  1483. CString strDest, strMask, strRouter;
  1484. ::UtilCvtIpAddrToWstr(Dest, &strDest);
  1485. ::UtilCvtIpAddrToWstr(Mask, &strMask);
  1486. ::UtilCvtIpAddrToWstr(Router, &strRouter);
  1487. LV_ITEM lvi;
  1488. lvi.mask = LVIF_TEXT;
  1489. lvi.iItem = pList->GetItemCount();
  1490. lvi.iSubItem = 0;
  1491. lvi.pszText = (LPTSTR)(LPCTSTR) strDest;
  1492. lvi.iImage = 0;
  1493. lvi.stateMask = 0;
  1494. int nItem = pList->InsertItem(&lvi);
  1495. pList->SetItemText(nItem, 1, strMask);
  1496. pList->SetItemText(nItem, 2, strRouter);
  1497. } // while
  1498. // select the first item
  1499. if ( pList->GetItemCount() > 0 )
  1500. {
  1501. pList->SetItemState( 0, LVIS_SELECTED, LVIS_SELECTED );
  1502. }
  1503. HandleActivationRouteArray();
  1504. } // if route array
  1505. else
  1506. {
  1507. switch(datatype)
  1508. {
  1509. case DhcpByteOption:
  1510. case DhcpWordOption:
  1511. case DhcpDWordOption:
  1512. {
  1513. if (optiontype == DhcpArrayTypeOption)
  1514. {
  1515. CListBox * pListBox =
  1516. reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_VALUES));
  1517. CEdit *pValue = reinterpret_cast<CEdit *>
  1518. ( GetDlgItem( IDC_EDIT_VALUE ));
  1519. CString strValue;
  1520. long lValue;
  1521. Assert(pListBox);
  1522. pListBox->ResetContent();
  1523. for (int i = 0; i < optValue.QueryUpperBound(); i++) {
  1524. lValue = optValue.QueryNumber(i);
  1525. if (bUseHex)
  1526. {
  1527. strValue.Format(_T("0x%x"), lValue);
  1528. }
  1529. else
  1530. {
  1531. strValue.Format(_T("%lu"), lValue);
  1532. }
  1533. pListBox->AddString(strValue);
  1534. } // for
  1535. if ( pListBox->GetCount() > 0 )
  1536. {
  1537. pListBox->SetCurSel( 0 );
  1538. }
  1539. // Convert the number in the edit box
  1540. pValue->GetWindowText( strValue );
  1541. if ( !strValue.IsEmpty())
  1542. {
  1543. DWORD maxVal;
  1544. if ( DhcpByteOption == datatype )
  1545. {
  1546. maxVal = 0xff;
  1547. }
  1548. else if ( DhcpWordOption == datatype )
  1549. {
  1550. maxVal = 0xffff;
  1551. }
  1552. else
  1553. {
  1554. maxVal = 0xffffffff;
  1555. }
  1556. FGetCtrlDWordValue( pValue->GetSafeHwnd(),
  1557. ( DWORD * )&lValue, 0, maxVal );
  1558. if ( bUseHex )
  1559. {
  1560. strValue.Format( _T("0x%x"), lValue );
  1561. }
  1562. else
  1563. {
  1564. strValue.Format( _T("%lu"), lValue );
  1565. }
  1566. pValue->SetWindowText( strValue );
  1567. } // if
  1568. HandleActivationValueArray();
  1569. } // if array type
  1570. else
  1571. {
  1572. CString strValue;
  1573. optValue.QueryDisplayString(strValue);
  1574. CWnd * pWnd = GetDlgItem(IDC_EDIT_DWORD);
  1575. Assert(pWnd);
  1576. pWnd->SetWindowText(strValue);
  1577. } // else single valued
  1578. break;
  1579. }
  1580. case DhcpIpAddressOption:
  1581. {
  1582. if (optiontype == DhcpArrayTypeOption)
  1583. {
  1584. CListBox * pListBox =
  1585. reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_IP_ADDRS));
  1586. Assert(pListBox);
  1587. pListBox->ResetContent();
  1588. for (int i = 0; i < optValue.QueryUpperBound(); i++)
  1589. {
  1590. CString strValue;
  1591. DHCP_IP_ADDRESS ipAddress = optValue.QueryIpAddr(i);
  1592. if (ipAddress)
  1593. {
  1594. ::UtilCvtIpAddrToWstr(ipAddress, &strValue);
  1595. pListBox->AddString(strValue);
  1596. }
  1597. } // for
  1598. HandleActivationIpArray();
  1599. } // if array type
  1600. else
  1601. {
  1602. CWndIpAddress * pIpAddr =
  1603. reinterpret_cast<CWndIpAddress *>(GetDlgItem(IDC_IPADDR_ADDRESS));
  1604. DHCP_IP_ADDRESS ipAddress = optValue.QueryIpAddr();
  1605. if (ipAddress)
  1606. pIpAddr->SetAddress(ipAddress);
  1607. else
  1608. pIpAddr->ClearAddress();
  1609. } // else single valued
  1610. break;
  1611. }
  1612. case DhcpStringDataOption:
  1613. {
  1614. if (optiontype == DhcpArrayTypeOption)
  1615. {
  1616. CListBox * pListBox =
  1617. reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_STRING_ARRAY ));
  1618. Assert(pListBox);
  1619. pListBox->ResetContent();
  1620. CString str;
  1621. for (int i = 0; i < optValue.QueryUpperBound(); i++)
  1622. {
  1623. str = optValue.QueryString( i );
  1624. if ( !str.IsEmpty())
  1625. {
  1626. pListBox->AddString( optValue.QueryString( i ));
  1627. }
  1628. str = L"";
  1629. } // for
  1630. if ( pListBox->GetCount() > 0 )
  1631. {
  1632. pListBox->SetCurSel( 0 );
  1633. }
  1634. HandleActivationStringArray();
  1635. } // if array type
  1636. else
  1637. {
  1638. CWnd * pWnd = GetDlgItem(IDC_EDIT_STRING_VALUE);
  1639. pWnd->SetWindowText(optValue.QueryString());
  1640. } // else single valued
  1641. break;
  1642. }
  1643. case DhcpDWordDWordOption:
  1644. {
  1645. if (optiontype == DhcpArrayTypeOption)
  1646. {
  1647. CListBox * pListBox =
  1648. reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_VALUES));
  1649. CEdit *pValue =
  1650. reinterpret_cast<CEdit *>( GetDlgItem( IDC_EDIT_VALUE ));
  1651. CString strValue;
  1652. DWORD_DWORD value;
  1653. ULARGE_INTEGER ulValue;
  1654. Assert(pListBox);
  1655. pListBox->ResetContent();
  1656. for (int i = 0; i < optValue.QueryUpperBound(); i++)
  1657. {
  1658. DWORD_DWORD dwdwValue = optValue.QueryDwordDword(i);
  1659. ::UtilConvertDwordDwordToString(&dwdwValue, &strValue, !bUseHex);
  1660. pListBox->AddString(strValue);
  1661. } // for
  1662. if ( pListBox->GetCount() > 0 )
  1663. {
  1664. pListBox->SetCurSel( 0 );
  1665. }
  1666. pValue->GetWindowText( strValue );
  1667. if ( !strValue.IsEmpty())
  1668. {
  1669. UtilConvertStringToDwordDword( strValue, &value );
  1670. UtilConvertDwordDwordToString( &value, &strValue, !bUseHex );
  1671. pValue->SetWindowText( strValue );
  1672. } // if
  1673. HandleActivationValueArray();
  1674. } // if array type
  1675. else
  1676. {
  1677. CString strValue;
  1678. optValue.QueryDisplayString(strValue);
  1679. CWnd * pWnd = GetDlgItem(IDC_EDIT_DWORD);
  1680. Assert(pWnd);
  1681. pWnd->SetWindowText(strValue);
  1682. } // else single valued
  1683. break;
  1684. }
  1685. case DhcpBinaryDataOption:
  1686. case DhcpEncapsulatedDataOption:
  1687. {
  1688. const CByteArray * pbaData = optValue.QueryBinaryArray();
  1689. int nDataSize = (int)pbaData->GetSize();
  1690. LPBYTE pData = (LPBYTE) pbaData->GetData();
  1691. memset(m_BinaryBuffer, 0, sizeof(m_BinaryBuffer));
  1692. if (pData)
  1693. {
  1694. memcpy(m_BinaryBuffer, pData, nDataSize);
  1695. }
  1696. SendDlgItemMessage(IDC_VALUEDATA, HEM_SETBUFFER, (WPARAM)
  1697. nDataSize, (LPARAM) m_BinaryBuffer);
  1698. break;
  1699. } // case ..
  1700. default:
  1701. {
  1702. Assert(FALSE);
  1703. break;
  1704. }
  1705. } // switch
  1706. }
  1707. } // COptionsCfgPropPage::FillDataEntry()
  1708. void COptionsCfgPropPage::InitListCtrl()
  1709. {
  1710. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1711. // set image lists
  1712. m_StateImageList.Create(IDB_LIST_STATE, 16, 1, RGB(255, 0, 0));
  1713. m_listctrlOptions.SetImageList(NULL, LVSIL_NORMAL);
  1714. m_listctrlOptions.SetImageList(NULL, LVSIL_SMALL);
  1715. m_listctrlOptions.SetImageList(&m_StateImageList, LVSIL_STATE);
  1716. // insert a column so we can see the items
  1717. LV_COLUMN lvc;
  1718. CString strColumnHeader;
  1719. for (int i = 0; i < MAX_COLUMNS; i++)
  1720. {
  1721. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  1722. lvc.iSubItem = i;
  1723. lvc.fmt = LVCFMT_LEFT;
  1724. lvc.cx = COLUMN_WIDTHS[i];
  1725. strColumnHeader.LoadString(COLUMN_HEADERS[i]);
  1726. lvc.pszText = (LPTSTR) (LPCTSTR) strColumnHeader;
  1727. m_listctrlOptions.InsertColumn(i, &lvc);
  1728. }
  1729. m_listctrlOptions.SetFullRowSel(TRUE);
  1730. }
  1731. void COptionsCfgPropPage::OnDestroy()
  1732. {
  1733. CImageList * pStateImageList = NULL;
  1734. // if the control has been initialized, we need to cleanup
  1735. if (m_listctrlOptions.GetSafeHwnd() != NULL)
  1736. {
  1737. pStateImageList = m_listctrlOptions.SetImageList(NULL, LVSIL_STATE);
  1738. if (pStateImageList) {
  1739. //pStateImageList->DeleteImageList();
  1740. }
  1741. // The OptionTrackers get delete in the destructor
  1742. m_listctrlOptions.DeleteAllItems();
  1743. }
  1744. m_listctrlOptions.DestroyWindow();
  1745. CPropertyPageBase::OnDestroy();
  1746. }
  1747. void COptionsCfgPropPage::OnItemchangedListOptions(NMHDR* pNMHDR, LRESULT* pResult)
  1748. {
  1749. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1750. if (pNMListView->uChanged & LVIF_STATE)
  1751. {
  1752. BOOL bUpdate = FALSE, bEnable = FALSE;
  1753. UINT uFlags = pNMListView->uOldState ^ pNMListView->uNewState;
  1754. COptionTracker* pCurOptTracker =
  1755. reinterpret_cast<COptionTracker *>
  1756. (m_listctrlOptions.GetItemData(pNMListView->iItem));
  1757. CDhcpOption* pCurOption = pCurOptTracker->m_pOption;
  1758. BOOL bOldSelected = pNMListView->uOldState & LVIS_SELECTED;
  1759. BOOL bNewSelected = pNMListView->uNewState & LVIS_SELECTED;
  1760. BOOL bStateImageChanged =
  1761. (pNMListView->uOldState & LVIS_STATEIMAGEMASK) !=
  1762. (pNMListView->uNewState & LVIS_STATEIMAGEMASK);
  1763. BOOL bIsSelected = m_listctrlOptions.IsSelected(pNMListView->iItem);
  1764. // has this item been selected?
  1765. if (!bOldSelected && bNewSelected)
  1766. {
  1767. // check to see if this item is checked
  1768. bEnable = m_listctrlOptions.GetCheck(pNMListView->iItem);
  1769. bUpdate = TRUE;
  1770. }
  1771. // has item been checked/unchecked?
  1772. if (bStateImageChanged && m_bInitialized)
  1773. {
  1774. // mark this as dirty and enable apply button
  1775. pCurOptTracker->SetDirty(TRUE);
  1776. SetDirty(TRUE);
  1777. // update the state in the option tracker
  1778. UINT uCurrentState = m_listctrlOptions.GetCheck(pNMListView->iItem)
  1779. ? OPTION_STATE_ACTIVE
  1780. : OPTION_STATE_INACTIVE;
  1781. pCurOptTracker->SetCurrentState(uCurrentState);
  1782. // we force the the selection of an item if the user changes it's checkbox state
  1783. if (!bIsSelected)
  1784. {
  1785. m_listctrlOptions.SelectItem(pNMListView->iItem);
  1786. }
  1787. } // if
  1788. // if we are changing the check box on a selected item, then update
  1789. if ((bStateImageChanged && bIsSelected))
  1790. {
  1791. bEnable = (pNMListView->uNewState &
  1792. INDEXTOSTATEIMAGEMASK(LISTVIEWEX_CHECKED)) > 0;
  1793. bUpdate = TRUE;
  1794. }
  1795. // item needs to be updated
  1796. if (bUpdate)
  1797. {
  1798. BOOL fRouteArray = ( !pCurOption->IsClassOption() &&
  1799. (DHCP_OPTION_ID_CSR == pCurOption->QueryId()) &&
  1800. DhcpUnaryElementTypeOption == pCurOption->QueryOptType() &&
  1801. DhcpBinaryDataOption == pCurOption->QueryDataType());
  1802. SwitchDataEntry( pCurOption->QueryDataType(),
  1803. pCurOption->QueryOptType(), fRouteArray, bEnable);
  1804. FillDataEntry(pCurOption);
  1805. } // if
  1806. } // if
  1807. *pResult = 0;
  1808. } // COptionsCfgPropPage::OnItemchangedListOptions()
  1809. BOOL COptionsCfgPropPage::OnSetActive()
  1810. {
  1811. return CPropertyPageBase::OnSetActive();
  1812. }
  1813. void COptionsCfgPropPage::HandleActivationStringArray()
  1814. {
  1815. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  1816. if (nSelectedIndex == -1)
  1817. {
  1818. // Nothing selected
  1819. return;
  1820. }
  1821. COptionTracker* pOptTracker =
  1822. reinterpret_cast<COptionTracker *>( m_listctrlOptions.GetItemData( nSelectedIndex ));
  1823. _ASSERT(pOptTracker);
  1824. // Get the OptionValue object
  1825. CDhcpOption * pOption = pOptTracker->m_pOption;
  1826. CDhcpOptionValue & optValue = pOption->QueryValue();
  1827. CListBox *pList = reinterpret_cast<CListBox *>( GetDlgItem( IDC_LIST_STRING_ARRAY ));
  1828. CButton *pAdd = reinterpret_cast<CButton *>( GetDlgItem( IDC_BUTTON_STRING_ARRAY_ADD ));
  1829. CButton *pRemove = reinterpret_cast<CButton *>( GetDlgItem( IDC_BUTTON_STRING_ARRAY_REMOVE ));
  1830. CButton *pUp = reinterpret_cast<CButton *>( GetDlgItem( IDC_BUTTON_STRING_ARRAY_UP ));
  1831. CButton *pDown = reinterpret_cast<CButton *>( GetDlgItem( IDC_BUTTON_STRING_ARRAY_DOWN ));
  1832. CEdit *pEdit = reinterpret_cast<CEdit *>( GetDlgItem( IDC_EDIT_STRING ));
  1833. bool enableAllowed = (pList->IsWindowEnabled() == TRUE)?true:false;
  1834. CString strValue;
  1835. pEdit->GetWindowText( strValue );
  1836. pAdd->EnableWindow( (!strValue.IsEmpty()) && enableAllowed);
  1837. // Fill optionvalue with list entries.
  1838. optValue.SetUpperBound( pList->GetCount());
  1839. CString str;
  1840. for ( int i = 0; i < pList->GetCount(); i++ )
  1841. {
  1842. pList->GetText( i, str );
  1843. optValue.SetString( str, i );
  1844. } // for
  1845. if ( pList->GetCount() == 0 )
  1846. {
  1847. pRemove->EnableWindow( FALSE );
  1848. pUp->EnableWindow( FALSE );
  1849. pDown->EnableWindow( FALSE );
  1850. return;
  1851. }
  1852. int nSel = pList->GetCurSel();
  1853. if ( LB_ERR != nSel )
  1854. {
  1855. pRemove->EnableWindow(enableAllowed);
  1856. pUp->EnableWindow( (nSel > 0) && enableAllowed);
  1857. pDown->EnableWindow( (pList->GetCount() > ( nSel + 1 )) && enableAllowed);
  1858. } // if
  1859. // check if the focus in on a disabled control
  1860. // If yes, put the focus back to list box
  1861. if ( !::IsWindowEnabled( ::GetFocus())) {
  1862. pList->SetFocus();
  1863. }
  1864. } // COptionsCfgPropPage::HandleActivationStringArray()
  1865. void COptionsCfgPropPage::HandleActivationIpArray()
  1866. {
  1867. CString strServerName;
  1868. CWndIpAddress * pIpAddr = reinterpret_cast<CWndIpAddress *>(GetDlgItem(IDC_IPADDR_SERVER_ADDRESS));
  1869. CButton * pResolve = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_RESOLVE));
  1870. CButton * pAdd = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_ADD));
  1871. CButton * pRemove = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_DELETE));
  1872. CButton * pUp = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_UP));
  1873. CButton * pDown = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_IPADDR_DOWN));
  1874. CEdit * pServerName = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_SERVER_NAME));
  1875. CListBox * pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_IP_ADDRS));
  1876. bool enableAllowed = (pListBox->IsWindowEnabled() == TRUE)?true:false;
  1877. // set the resolve button
  1878. pServerName->GetWindowText(strServerName);
  1879. pResolve->EnableWindow((strServerName.GetLength() > 0) && enableAllowed);
  1880. // the add button
  1881. DWORD dwIpAddr = 0;
  1882. pIpAddr->GetAddress(&dwIpAddr);
  1883. if (GetFocus() == pAdd &&
  1884. dwIpAddr == 0)
  1885. {
  1886. pIpAddr->SetFocus();
  1887. SetDefID(IDOK);
  1888. }
  1889. pAdd->EnableWindow((dwIpAddr != 0) && enableAllowed);
  1890. // Make sure something in listbox is selected
  1891. if ( pListBox->GetCount() > 0 ) {
  1892. if ( LB_ERR == pListBox->GetCurSel()) {
  1893. pListBox->SetCurSel( 0 ); // select the first one
  1894. }
  1895. }
  1896. // the remove button
  1897. if (GetFocus() == pRemove &&
  1898. pListBox->GetCurSel() < 0)
  1899. {
  1900. pIpAddr->SetFocus();
  1901. SetDefID(IDOK);
  1902. }
  1903. pRemove->EnableWindow((pListBox->GetCurSel() >= 0) && enableAllowed);
  1904. // up and down buttons
  1905. BOOL bEnableUp = (pListBox->GetCurSel() >= 0) && (pListBox->GetCurSel() != 0);
  1906. pUp->EnableWindow(bEnableUp && enableAllowed);
  1907. BOOL bEnableDown = (pListBox->GetCurSel() >= 0) && (pListBox->GetCurSel() < pListBox->GetCount() - 1);
  1908. pDown->EnableWindow(bEnableDown && enableAllowed);
  1909. } // COptionsCfgPropPage::HandleActivationIpArray()
  1910. void COptionsCfgPropPage::HandleActivationValueArray()
  1911. {
  1912. CButton * pAdd = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_ADD));
  1913. CButton * pRemove = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_DELETE));
  1914. CButton * pUp = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_UP));
  1915. CButton * pDown = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON_VALUE_DOWN));
  1916. CButton * pRadioDecimal = reinterpret_cast<CButton *>(GetDlgItem(IDC_RADIO_DECIMAL));
  1917. CEdit * pValue = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_VALUE));
  1918. CListBox * pListBox = reinterpret_cast<CListBox *>(GetDlgItem(IDC_LIST_VALUES));
  1919. bool enableAllowed = (pListBox->IsWindowEnabled() == TRUE)?true:false;
  1920. CString strValue;
  1921. pValue->GetWindowText( strValue );
  1922. pAdd->EnableWindow( !strValue.IsEmpty() && enableAllowed);
  1923. if ( pListBox->GetCount() == 0 )
  1924. {
  1925. pRemove->EnableWindow( FALSE );
  1926. pUp->EnableWindow( FALSE );
  1927. pDown->EnableWindow( FALSE );
  1928. return;
  1929. }
  1930. int nSel = pListBox->GetCurSel();
  1931. if ( LB_ERR != nSel )
  1932. {
  1933. pRemove->EnableWindow( enableAllowed );
  1934. pUp->EnableWindow( (nSel > 0) && enableAllowed );
  1935. pDown->EnableWindow( (pListBox->GetCount() > ( nSel + 1 ))
  1936. && enableAllowed);
  1937. }
  1938. } // COptionsCfgPropPage::HandleActivationValueArray()
  1939. void COptionsCfgPropPage::HandleActivationRouteArray(
  1940. CDhcpOptionValue *optValue
  1941. )
  1942. {
  1943. // this route will enable the right dialog items and also set
  1944. // focus correctly.
  1945. // get the routes list control
  1946. CListCtrl *pList = reinterpret_cast<CListCtrl *>(
  1947. GetDlgItem( IDC_LIST_OF_ROUTES ) );
  1948. bool enableAllowed = (pList->IsWindowEnabled() == TRUE)?true:false;
  1949. // get the add and remove buttons
  1950. CButton *pAdd = reinterpret_cast<CButton *>(
  1951. GetDlgItem(IDC_BUTTON_ROUTE_ADD) );
  1952. CButton *pRemove = reinterpret_cast<CButton *>(
  1953. GetDlgItem(IDC_BUTTON_ROUTE_DEL) );
  1954. if( optValue )
  1955. {
  1956. // also, format the whole list of ip addresses into
  1957. // binary type.. allocate large enough buffer
  1958. int nItems = pList->GetItemCount();
  1959. LPBYTE Buffer = new BYTE [sizeof(DWORD)*4 * nItems];
  1960. if( NULL != Buffer )
  1961. {
  1962. int BufSize = 0;
  1963. for( int i = 0 ; i < nItems ; i ++ )
  1964. {
  1965. DHCP_IP_ADDRESS Dest, Mask, Router;
  1966. Dest = UtilCvtWstrToIpAddr(pList->GetItemText(i, 0));
  1967. Mask = UtilCvtWstrToIpAddr(pList->GetItemText(i, 1));
  1968. Router = UtilCvtWstrToIpAddr(pList->GetItemText(i, 2));
  1969. Dest = htonl(Dest);
  1970. Router = htonl(Router);
  1971. int nBitsInMask = 0;
  1972. while( Mask != 0 ) {
  1973. nBitsInMask ++; Mask = (Mask << 1);
  1974. }
  1975. // first add destination descriptor
  1976. // first byte contains # of bits in mask
  1977. // next few bytes contain the dest address for only
  1978. // the significant octets
  1979. Buffer[BufSize++] = (BYTE)nBitsInMask;
  1980. memcpy(&Buffer[BufSize], &Dest, (nBitsInMask+7)/8);
  1981. BufSize += (nBitsInMask+7)/8;
  1982. // now just copy the router address
  1983. memcpy(&Buffer[BufSize], &Router, sizeof(Router));
  1984. BufSize += sizeof(Router);
  1985. } // for
  1986. // now write back the option value
  1987. DHCP_OPTION_DATA_ELEMENT DataElement = {DhcpBinaryDataOption };
  1988. DHCP_OPTION_DATA Data = { 1, &DataElement };
  1989. DataElement.Element.BinaryDataOption.DataLength = BufSize;
  1990. DataElement.Element.BinaryDataOption.Data = Buffer;
  1991. optValue->SetData( &Data );
  1992. delete[] Buffer;
  1993. } // if
  1994. } // if
  1995. // enable the remove button only if there are any
  1996. // elements at all
  1997. pRemove->EnableWindow( (pList->GetItemCount() > 0) && enableAllowed );
  1998. // Set the focus on Add
  1999. pAdd->SetFocus();
  2000. } // COptionsCfgPropPage::HandleActivationRouteArray()
  2001. BOOL COptionsCfgPropPage::OnApply()
  2002. {
  2003. BOOL bErrors = FALSE;
  2004. DWORD err = 0;
  2005. LPCTSTR pClassName;
  2006. COptionsConfig * pOptConfig = reinterpret_cast<COptionsConfig *>(GetHolder());
  2007. LPWSTR pszServerAddr = pOptConfig->GetServerAddress();
  2008. if (IsDirty()) {
  2009. BEGIN_WAIT_CURSOR;
  2010. // loop through all vendors first
  2011. POSITION posv = ((COptionsConfig *)
  2012. GetHolder())->m_listVendorClasses.GetHeadPosition();
  2013. while (posv) {
  2014. CVendorTracker * pVendorTracker =
  2015. ((COptionsConfig *) GetHolder())->m_listVendorClasses.GetNext(posv);
  2016. // loop through all classes and see if we have any options we need to update
  2017. POSITION pos = pVendorTracker->m_listUserClasses.GetHeadPosition();
  2018. while (pos) {
  2019. CClassTracker * pClassTracker =
  2020. pVendorTracker->m_listUserClasses.GetNext(pos);
  2021. pClassName = pClassTracker->m_strClassName.IsEmpty()
  2022. ? NULL
  2023. : (LPCTSTR) pClassTracker->m_strClassName;
  2024. POSITION posOption = pClassTracker->m_listOptions.GetHeadPosition();
  2025. while (posOption) {
  2026. COptionTracker * pCurOptTracker =
  2027. pClassTracker->m_listOptions.GetNext(posOption);
  2028. if (pCurOptTracker->IsDirty()) {
  2029. // we need to update this option
  2030. CDhcpOption * pCurOption = pCurOptTracker->m_pOption;
  2031. CDhcpOptionValue & optValue = pCurOption->QueryValue();
  2032. // check to see if the option has changed
  2033. if ((pCurOptTracker->GetInitialState() == OPTION_STATE_INACTIVE) &&
  2034. (pCurOptTracker->GetCurrentState() == OPTION_STATE_INACTIVE)) {
  2035. // the state hasn't changed, the user must have changed the
  2036. // state and then restored it to its original value
  2037. err = ERROR_SUCCESS;
  2038. }
  2039. else if ((pCurOptTracker->GetInitialState() == OPTION_STATE_ACTIVE) &&
  2040. (pCurOptTracker->GetCurrentState() == OPTION_STATE_INACTIVE)) {
  2041. // if it is a vendor specific or class ID option, call the V5 api
  2042. if ( pOptConfig->m_liServerVersion.QuadPart >= DHCP_NT5_VERSION) {
  2043. err = ::DhcpRemoveOptionValueV5(pszServerAddr,
  2044. pCurOption->IsVendor() ? DHCP_FLAGS_OPTION_IS_VENDOR : 0,
  2045. pCurOption->QueryId(),
  2046. (LPTSTR) pClassName,
  2047. (LPTSTR) pCurOption->GetVendor(),
  2048. &pOptConfig->m_pOptionValueEnum->m_dhcpOptionScopeInfo ) ;
  2049. }
  2050. else {
  2051. // need to remove this option for either global, scope or res client
  2052. err = ::DhcpRemoveOptionValue(pszServerAddr,
  2053. pCurOption->QueryId(),
  2054. &pOptConfig->m_pOptionValueEnum->m_dhcpOptionScopeInfo ) ;
  2055. }
  2056. } // elseif
  2057. else {
  2058. // check option 33
  2059. if ((pCurOption->QueryId() == 33 || pCurOption->QueryId() == 21) &&
  2060. ( !pCurOption->IsVendor()) &&
  2061. (pCurOption->QueryValue().QueryUpperBound()) % 2 != 0) {
  2062. // special case for option 33 & 21. Make sure it is a set of IP addres pairs
  2063. // and make sure we pick the right page to select
  2064. int nId = pClassName ? 1 : 0;
  2065. PropSheet_SetCurSel(GetHolder()->GetSheetWindow(), GetSafeHwnd(), nId);
  2066. SelectOption(pCurOption);
  2067. ::DhcpMessageBox(IDS_ERR_OPTION_ADDR_PAIRS);
  2068. m_listctrlOptions.SetFocus();
  2069. return 0;
  2070. } // if
  2071. // we are just updating this option
  2072. DHCP_OPTION_DATA * pOptData;
  2073. err = optValue.CreateOptionDataStruct(&pOptData);
  2074. if (err) {
  2075. ::DhcpMessageBox(err);
  2076. RESTORE_WAIT_CURSOR;
  2077. bErrors = TRUE;
  2078. continue;
  2079. }
  2080. // if it is a vendor specific or class ID option, call the V5 api
  2081. if ( ((COptionsConfig *)GetHolder())->m_liServerVersion.QuadPart >= DHCP_NT5_VERSION ) {
  2082. err = ::DhcpSetOptionValueV5(pszServerAddr,
  2083. pCurOption->IsVendor() ? DHCP_FLAGS_OPTION_IS_VENDOR : 0,
  2084. pCurOption->QueryId(),
  2085. (LPTSTR) pClassName,
  2086. (LPTSTR) pCurOption->GetVendor(),
  2087. &pOptConfig->m_pOptionValueEnum->m_dhcpOptionScopeInfo,
  2088. pOptData);
  2089. }
  2090. else {
  2091. err = ::DhcpSetOptionValue(pszServerAddr,
  2092. pCurOption->QueryId(),
  2093. &pOptConfig->m_pOptionValueEnum->m_dhcpOptionScopeInfo,
  2094. pOptData);
  2095. }
  2096. } // else
  2097. if (err) {
  2098. ::DhcpMessageBox(err);
  2099. RESTORE_WAIT_CURSOR;
  2100. bErrors = TRUE;
  2101. }
  2102. else {
  2103. // all done with this option. Mark as clean and update
  2104. // the new initial state to the current state.
  2105. pCurOptTracker->SetDirty(FALSE);
  2106. pCurOptTracker->SetInitialState(pCurOptTracker->GetCurrentState());
  2107. }
  2108. } // endif option->IsDirty()
  2109. } // while user class options
  2110. } // while User class loop
  2111. } // while Vendor loop
  2112. END_WAIT_CURSOR;
  2113. }// endif IsDirty()
  2114. if (bErrors) {
  2115. return 0;
  2116. }
  2117. else {
  2118. BOOL bRet = CPropertyPageBase::OnApply();
  2119. if (bRet == FALSE) {
  2120. // Something bad happened... grab the error code
  2121. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  2122. ::DhcpMessageBox(GetHolder()->GetError());
  2123. }
  2124. return bRet;
  2125. } // else
  2126. } // COptionsCfgPropPage::OnApply()
  2127. // need to refresh the UI on the main app thread...
  2128. BOOL COptionsCfgPropPage::OnPropertyChange(BOOL bScope, LONG_PTR *ChangeMask)
  2129. {
  2130. SPITFSNode spNode;
  2131. spNode = GetHolder()->GetNode();
  2132. CMTDhcpHandler * pMTHandler = GETHANDLER(CMTDhcpHandler, spNode);
  2133. pMTHandler->OnRefresh(spNode, NULL, 0, 0, 0);
  2134. return FALSE;
  2135. }
  2136. //
  2137. // See if any of the edit fields have been changed and perform the alteration.
  2138. // Return TRUE if the value was changed.
  2139. //
  2140. BOOL COptionsCfgPropPage::HandleValueEdit()
  2141. {
  2142. LONG err = 0;
  2143. int nSelectedIndex = m_listctrlOptions.GetSelectedItem();
  2144. if (nSelectedIndex > -1)
  2145. {
  2146. COptionTracker * pOptTracker =
  2147. reinterpret_cast<COptionTracker *>(m_listctrlOptions.GetItemData(nSelectedIndex));
  2148. CEdit * pDwordEdit = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_DWORD));
  2149. CWndIpAddress * pIpAddr = reinterpret_cast<CWndIpAddress *>(GetDlgItem(IDC_IPADDR_ADDRESS));
  2150. CEdit * pString = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_STRING_VALUE));
  2151. CDhcpOptionValue & dhcValue = pOptTracker->m_pOption->QueryValue();
  2152. DHCP_OPTION_DATA_TYPE dhcType = dhcValue.QueryDataType();
  2153. DHCP_IP_ADDRESS dhipa ;
  2154. CString strEdit;
  2155. BOOL bModified = FALSE;
  2156. switch ( dhcType )
  2157. {
  2158. case DhcpByteOption:
  2159. case DhcpWordOption:
  2160. case DhcpDWordOption:
  2161. case DhcpBinaryDataOption:
  2162. {
  2163. DWORD dwResult;
  2164. DWORD dwMask = 0xFFFFFFFF;
  2165. if (dhcType == DhcpByteOption)
  2166. {
  2167. dwMask = 0xFF;
  2168. }
  2169. else if (dhcType == DhcpWordOption)
  2170. {
  2171. dwMask = 0xFFFF;
  2172. }
  2173. if (!FGetCtrlDWordValue(pDwordEdit->GetSafeHwnd(), &dwResult, 0, dwMask))
  2174. {
  2175. return FALSE;
  2176. }
  2177. // only mark this dirty if the value has changed as we may just
  2178. // be updating the UI
  2179. if (dwResult != (DWORD) dhcValue.QueryNumber(0))
  2180. {
  2181. bModified = TRUE ;
  2182. (void)dhcValue.SetNumber(dwResult, 0);
  2183. ASSERT(err == FALSE);
  2184. }
  2185. break;
  2186. }
  2187. case DhcpDWordDWordOption:
  2188. {
  2189. DWORD_DWORD dwdw;
  2190. CString strValue;
  2191. pDwordEdit->GetWindowText(strValue);
  2192. UtilConvertStringToDwordDword(strValue, &dwdw);
  2193. // only mark this dirty if the value has changed as we may just
  2194. // be updating the UI
  2195. if (( dwdw.DWord1 != dhcValue.QueryDwordDword(0).DWord1 ) ||
  2196. ( dwdw.DWord2 != dhcValue.QueryDwordDword(0).DWord2 ))
  2197. {
  2198. bModified = TRUE;
  2199. dhcValue.SetDwordDword(dwdw, 0);
  2200. }
  2201. break;
  2202. }
  2203. case DhcpStringDataOption:
  2204. {
  2205. pString->GetWindowText( strEdit );
  2206. // only mark this dirty if the value has changed as we may just
  2207. // be updating the UI
  2208. if (strEdit.Compare(dhcValue.QueryString(0)) != 0)
  2209. {
  2210. bModified = TRUE;
  2211. err = dhcValue.SetString( strEdit, 0 );
  2212. }
  2213. break ;
  2214. }
  2215. case DhcpIpAddressOption:
  2216. {
  2217. if (!pIpAddr->GetModify())
  2218. {
  2219. break ;
  2220. }
  2221. if ( !pIpAddr->IsBlank() )
  2222. {
  2223. if ( !pIpAddr->GetAddress(&dhipa) )
  2224. {
  2225. err = ERROR_INVALID_PARAMETER;
  2226. break;
  2227. }
  2228. // only mark this dirty if the value has changed as we may just
  2229. // be updating the UI
  2230. if (dhipa != dhcValue.QueryIpAddr(0))
  2231. {
  2232. bModified = TRUE ;
  2233. err = dhcValue.SetIpAddr( dhipa, 0 );
  2234. }
  2235. }
  2236. break;
  2237. }
  2238. default:
  2239. {
  2240. Trace0("invalid value type in HandleValueEdit");
  2241. Assert( FALSE );
  2242. err = ERROR_INVALID_PARAMETER;
  2243. break;
  2244. }
  2245. }
  2246. if (err)
  2247. {
  2248. ::DhcpMessageBox(err);
  2249. }
  2250. else if (bModified)
  2251. {
  2252. pOptTracker->SetDirty(TRUE);
  2253. SetDirty(TRUE);
  2254. }
  2255. }
  2256. return err == 0 ;
  2257. }
  2258. /////////////////////////////////////////////////////////////////////////////
  2259. //
  2260. // COptionCfgGeneral page
  2261. //
  2262. /////////////////////////////////////////////////////////////////////////////
  2263. BEGIN_MESSAGE_MAP(COptionCfgGeneral, COptionsCfgPropPage)
  2264. //{{AFX_MSG_MAP(COptionCfgGeneral)
  2265. //}}AFX_MSG_MAP
  2266. END_MESSAGE_MAP()
  2267. IMPLEMENT_DYNCREATE(COptionCfgGeneral, COptionsCfgPropPage)
  2268. COptionCfgGeneral::COptionCfgGeneral()
  2269. : COptionsCfgPropPage(IDP_OPTION_BASIC)
  2270. {
  2271. //{{AFX_DATA_INIT(COptionCfgGeneral)
  2272. //}}AFX_DATA_INIT
  2273. }
  2274. COptionCfgGeneral::COptionCfgGeneral(UINT nIDTemplate, UINT nIDCaption)
  2275. : COptionsCfgPropPage(nIDTemplate, nIDCaption)
  2276. {
  2277. }
  2278. COptionCfgGeneral::~COptionCfgGeneral()
  2279. {
  2280. }
  2281. void COptionCfgGeneral::DoDataExchange(CDataExchange* pDX)
  2282. {
  2283. COptionsCfgPropPage::DoDataExchange(pDX);
  2284. //{{AFX_DATA_MAP(COptionCfgGeneral)
  2285. //}}AFX_DATA_MAP
  2286. }
  2287. BOOL COptionCfgGeneral::OnInitDialog()
  2288. {
  2289. COptionsCfgPropPage::OnInitDialog();
  2290. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2291. // check to see if we should focus on a particular option
  2292. COptionsConfig * pOptionsConfig = (COptionsConfig *) GetHolder();
  2293. if (pOptionsConfig->m_dhcpStartId != 0xffffffff)
  2294. {
  2295. // check to see if this option is on the advanced page
  2296. if (!pOptionsConfig->m_strStartVendor.IsEmpty() ||
  2297. !pOptionsConfig->m_strStartClass.IsEmpty())
  2298. {
  2299. // this option is on the advanced page
  2300. ::PostMessage(pOptionsConfig->GetSheetWindow(), PSM_SETCURSEL, (WPARAM)1, NULL);
  2301. return TRUE;
  2302. }
  2303. // find the option to select
  2304. OnSelectOption(0,0);
  2305. }
  2306. SetDirty(FALSE);
  2307. return TRUE; // return TRUE unless you set the focus to a control
  2308. // EXCEPTION: OCX Property Pages should return FALSE
  2309. }
  2310. /////////////////////////////////////////////////////////////////////////////
  2311. //
  2312. // COptionCfgAdvanced page
  2313. //
  2314. /////////////////////////////////////////////////////////////////////////////
  2315. BEGIN_MESSAGE_MAP(COptionCfgAdvanced, COptionsCfgPropPage)
  2316. //{{AFX_MSG_MAP(COptionCfgAdvanced)
  2317. ON_CBN_SELENDOK(IDC_COMBO_USER_CLASS, OnSelendokComboUserClass)
  2318. ON_CBN_SELENDOK(IDC_COMBO_VENDOR_CLASS, OnSelendokComboVendorClass)
  2319. //}}AFX_MSG_MAP
  2320. ON_MESSAGE(WM_SELECTCLASSES, OnSelectClasses)
  2321. END_MESSAGE_MAP()
  2322. IMPLEMENT_DYNCREATE(COptionCfgAdvanced, COptionsCfgPropPage)
  2323. COptionCfgAdvanced::COptionCfgAdvanced()
  2324. : COptionsCfgPropPage(IDP_OPTION_ADVANCED)
  2325. {
  2326. //{{AFX_DATA_INIT(COptionCfgAdvanced)
  2327. //}}AFX_DATA_INIT
  2328. m_helpMap.BuildMap(DhcpGetHelpMap(IDP_OPTION_ADVANCED));
  2329. }
  2330. COptionCfgAdvanced::COptionCfgAdvanced(UINT nIDTemplate, UINT nIDCaption)
  2331. : COptionsCfgPropPage(nIDTemplate, nIDCaption)
  2332. {
  2333. m_helpMap.BuildMap(DhcpGetHelpMap(IDP_OPTION_ADVANCED));
  2334. }
  2335. COptionCfgAdvanced::~COptionCfgAdvanced()
  2336. {
  2337. }
  2338. void COptionCfgAdvanced::DoDataExchange(CDataExchange* pDX)
  2339. {
  2340. COptionsCfgPropPage::DoDataExchange(pDX);
  2341. //{{AFX_DATA_MAP(COptionCfgAdvanced)
  2342. DDX_Control(pDX, IDC_COMBO_USER_CLASS, m_comboUserClasses);
  2343. DDX_Control(pDX, IDC_COMBO_VENDOR_CLASS, m_comboVendorClasses);
  2344. //}}AFX_DATA_MAP
  2345. }
  2346. BOOL COptionCfgAdvanced::OnInitDialog()
  2347. {
  2348. CPropertyPageBase::OnInitDialog();
  2349. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2350. // initialize the list control
  2351. InitListCtrl();
  2352. // initialize the option data
  2353. // this gets done in the general page init, only needs
  2354. // to be done once
  2355. /*
  2356. DWORD dwErr = ((COptionsConfig *) GetHolder())->InitData();
  2357. if (dwErr != ERROR_SUCCESS)
  2358. {
  2359. // CODEWORK: need to exit gracefull if this happens
  2360. ::DhcpMessageBox(dwErr);
  2361. }
  2362. */
  2363. // add the standard vendor class name
  2364. int nSel;
  2365. CString strVendor, strClass;
  2366. strVendor.LoadString(IDS_INFO_NAME_DHCP_DEFAULT);
  2367. nSel = m_comboVendorClasses.AddString(strVendor);
  2368. m_comboVendorClasses.SetCurSel(nSel);
  2369. // add the default user class name
  2370. strClass.LoadString(IDS_USER_STANDARD);
  2371. nSel = m_comboUserClasses.AddString(strClass);
  2372. m_comboUserClasses.SetCurSel(nSel);
  2373. // now add all the other classes
  2374. SPITFSNode spNode;
  2375. spNode = ((COptionsConfig *) GetHolder())->GetServerNode();
  2376. CDhcpServer * pServer = GETHANDLER(CDhcpServer, spNode);
  2377. CClassInfoArray ClassInfoArray;
  2378. // add all the classes to the appropriate classes to the dropdown
  2379. pServer->GetClassInfoArray(ClassInfoArray);
  2380. for (int i = 0; i < ClassInfoArray.GetSize(); i++)
  2381. {
  2382. if (!ClassInfoArray[i].bIsVendor)
  2383. m_comboUserClasses.AddString(ClassInfoArray[i].strName);
  2384. else
  2385. m_comboVendorClasses.AddString(ClassInfoArray[i].strName);
  2386. }
  2387. // now fill the options listbox with whatever class is selected
  2388. ((COptionsConfig *) GetHolder())->FillOptions(strVendor, strClass, m_listctrlOptions);
  2389. m_bNoClasses = FALSE;
  2390. // Create the type control switcher
  2391. m_cgsTypes.Create(this,IDC_DATA_ENTRY_ANCHOR,cgsPreCreateAll);
  2392. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_NONE, IDD_DATA_ENTRY_NONE, NULL);
  2393. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_DWORD, IDD_DATA_ENTRY_DWORD, NULL);
  2394. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_IPADDRESS, IDD_DATA_ENTRY_IPADDRESS, NULL);
  2395. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_IPADDRESS_ARRAY, IDD_DATA_ENTRY_IPADDRESS_ARRAY, NULL);
  2396. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_STRING, IDD_DATA_ENTRY_STRING, NULL);
  2397. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_BINARY_ARRAY, IDD_DATA_ENTRY_BINARY_ARRAY, NULL);
  2398. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_BINARY, IDD_DATA_ENTRY_BINARY, NULL);
  2399. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_ROUTE_ARRAY, IDD_DATA_ENTRY_ROUTE_ARRAY, NULL);
  2400. m_cgsTypes.AddGroup(IDC_DATA_ENTRY_STRING_ARRAY, IDD_DATA_ENTRY_STRING_ARRAY, NULL);
  2401. SwitchDataEntry(-1, -1, 0, TRUE);
  2402. m_bInitialized = TRUE;
  2403. // check to see if we should focus on a particular option
  2404. COptionsConfig * pOptionsConfig = (COptionsConfig *) GetHolder();
  2405. if (pOptionsConfig->m_dhcpStartId != 0xffffffff)
  2406. {
  2407. // yes, first select the appropriate vendor/ user class
  2408. Assert(!pOptionsConfig->m_strStartVendor.IsEmpty() ||
  2409. !pOptionsConfig->m_strStartClass.IsEmpty());
  2410. if (!pOptionsConfig->m_strStartVendor.IsEmpty())
  2411. m_comboVendorClasses.SelectString(-1, pOptionsConfig->m_strStartVendor);
  2412. if (!pOptionsConfig->m_strStartClass.IsEmpty())
  2413. m_comboUserClasses.SelectString(-1, pOptionsConfig->m_strStartClass);
  2414. // update the list of options
  2415. OnSelendokComboVendorClass();
  2416. // now find the option
  2417. OnSelectOption(0,0);
  2418. }
  2419. SetDirty(FALSE);
  2420. return TRUE; // return TRUE unless you set the focus to a control
  2421. // EXCEPTION: OCX Property Pages should return FALSE
  2422. }
  2423. void COptionCfgAdvanced::OnSelendokComboUserClass()
  2424. {
  2425. OnSelendokComboVendorClass();
  2426. }
  2427. void COptionCfgAdvanced::OnSelendokComboVendorClass()
  2428. {
  2429. // If we have classes defined then its time to switch up the list ctrl
  2430. if (m_bNoClasses == FALSE)
  2431. {
  2432. CString strSelectedVendor, strSelectedClass;
  2433. int nSelVendorIndex = m_comboVendorClasses.GetCurSel();
  2434. int nSelClassIndex = m_comboUserClasses.GetCurSel();
  2435. m_comboVendorClasses.GetLBText(nSelVendorIndex, strSelectedVendor);
  2436. m_comboUserClasses.GetLBText(nSelClassIndex, strSelectedClass);
  2437. // mark the page as not initiailzed while we redo the options
  2438. m_bInitialized = FALSE;
  2439. m_listctrlOptions.DeleteAllItems();
  2440. ((COptionsConfig *) GetHolder())->FillOptions(strSelectedVendor, strSelectedClass, m_listctrlOptions);
  2441. m_bInitialized = TRUE;
  2442. SwitchDataEntry( -1, -1, 0, TRUE );
  2443. }
  2444. }
  2445. long COptionCfgAdvanced::OnSelectClasses(UINT wParam, LONG lParam)
  2446. {
  2447. CString * pstrVendor = (CString *) ULongToPtr(wParam);
  2448. CString * pstrClass = (CString *) ULongToPtr(lParam);
  2449. if (pstrVendor->IsEmpty())
  2450. pstrVendor->LoadString(IDS_INFO_NAME_DHCP_DEFAULT);
  2451. if (pstrClass->IsEmpty())
  2452. pstrClass->LoadString(IDS_USER_STANDARD);
  2453. m_comboVendorClasses.SelectString(-1, *pstrVendor);
  2454. m_comboUserClasses.SelectString(-1, *pstrClass);
  2455. // update the list of options
  2456. OnSelendokComboVendorClass();
  2457. return 0;
  2458. }