Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

271 lines
6.5 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1997 **/
  4. /**********************************************************************/
  5. /*
  6. AddBootp.cpp
  7. dialog to add a bootp entry
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "addbootp.h"
  12. #include "server.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CAddBootpEntry dialog
  20. CAddBootpEntry::CAddBootpEntry
  21. (
  22. ITFSNode * pNode,
  23. LPCTSTR pServerAddress,
  24. CWnd* pParent /*=NULL*/
  25. )
  26. : CBaseDialog(CAddBootpEntry::IDD, pParent),
  27. m_pBootpTable(NULL)
  28. {
  29. //{{AFX_DATA_INIT(CAddBootpEntry)
  30. m_strFileName = _T("");
  31. m_strFileServer = _T("");
  32. m_strImageName = _T("");
  33. //}}AFX_DATA_INIT
  34. m_strServerAddress = pServerAddress;
  35. m_spNode.Set(pNode);
  36. }
  37. CAddBootpEntry::~CAddBootpEntry()
  38. {
  39. if (m_pBootpTable)
  40. free(m_pBootpTable);
  41. }
  42. void CAddBootpEntry::DoDataExchange(CDataExchange* pDX)
  43. {
  44. CBaseDialog::DoDataExchange(pDX);
  45. //{{AFX_DATA_MAP(CAddBootpEntry)
  46. DDX_Control(pDX, IDOK, m_buttonOk);
  47. DDX_Control(pDX, IDC_EDIT_BOOTP_IMAGE_NAME, m_editImageName);
  48. DDX_Control(pDX, IDC_EDIT_BOOTP_FILE_NAME, m_editFileName);
  49. DDX_Control(pDX, IDC_EDIT_BOOTP_FILE_SERVER, m_editFileServer);
  50. DDX_Text(pDX, IDC_EDIT_BOOTP_FILE_NAME, m_strFileName);
  51. DDX_Text(pDX, IDC_EDIT_BOOTP_FILE_SERVER, m_strFileServer);
  52. DDX_Text(pDX, IDC_EDIT_BOOTP_IMAGE_NAME, m_strImageName);
  53. //}}AFX_DATA_MAP
  54. }
  55. BEGIN_MESSAGE_MAP(CAddBootpEntry, CBaseDialog)
  56. //{{AFX_MSG_MAP(CAddBootpEntry)
  57. ON_EN_CHANGE(IDC_EDIT_BOOTP_FILE_NAME, OnChangeEditBootpFileName)
  58. ON_EN_CHANGE(IDC_EDIT_BOOTP_FILE_SERVER, OnChangeEditBootpFileServer)
  59. ON_EN_CHANGE(IDC_EDIT_BOOTP_IMAGE_NAME, OnChangeEditBootpImageName)
  60. //}}AFX_MSG_MAP
  61. END_MESSAGE_MAP()
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CAddBootpEntry message handlers
  64. BOOL CAddBootpEntry::OnInitDialog()
  65. {
  66. CBaseDialog::OnInitDialog();
  67. HandleActivation();
  68. return TRUE; // return TRUE unless you set the focus to a control
  69. // EXCEPTION: OCX Property Pages should return FALSE
  70. }
  71. DWORD CAddBootpEntry::GetBootpTable()
  72. {
  73. DWORD dwError = 0;
  74. LPDHCP_SERVER_CONFIG_INFO_V4 pServerConfig = NULL;
  75. BEGIN_WAIT_CURSOR;
  76. dwError = ::DhcpServerGetConfigV4(m_strServerAddress, &pServerConfig);
  77. END_WAIT_CURSOR;
  78. if (dwError != ERROR_SUCCESS)
  79. {
  80. ::DhcpMessageBox(dwError);
  81. return dwError;
  82. }
  83. Assert(pServerConfig);
  84. if (m_pBootpTable)
  85. {
  86. delete m_pBootpTable;
  87. m_pBootpTable = NULL;
  88. }
  89. m_nBootpTableLength = pServerConfig->cbBootTableString;
  90. if (m_nBootpTableLength > 0)
  91. {
  92. m_pBootpTable = (WCHAR *) malloc(m_nBootpTableLength);
  93. if (!m_pBootpTable)
  94. return ERROR_NOT_ENOUGH_MEMORY;
  95. // copy the bootp table into our local storage so we can modify it
  96. ::CopyMemory(m_pBootpTable, pServerConfig->wszBootTableString, m_nBootpTableLength);
  97. }
  98. // release the rpc memory
  99. ::DhcpRpcFreeMemory(pServerConfig);
  100. return dwError;
  101. }
  102. DWORD CAddBootpEntry::AddBootpEntryToTable()
  103. {
  104. UpdateData();
  105. // calculate the length of the new entry. Entries are stored as:
  106. // Image,FileServer,FileName<NULL>
  107. // So the length is the length of the three strings plus 3 characters
  108. // (two separators and a terminator). There is also a null terminator
  109. // for the entire string.
  110. int nNewBootpEntrySize = (m_strImageName.GetLength() +
  111. m_strFileServer.GetLength() +
  112. m_strFileName.GetLength() + 3) * sizeof(WCHAR);
  113. int nNewBootpTableLength, nStartIndex;
  114. nNewBootpTableLength = m_nBootpTableLength + nNewBootpEntrySize;
  115. WCHAR * pNewBootpTable;
  116. if (m_nBootpTableLength > 0)
  117. {
  118. nStartIndex = m_nBootpTableLength/sizeof(WCHAR) - 1;
  119. pNewBootpTable = (WCHAR *) realloc(m_pBootpTable, nNewBootpTableLength);
  120. }
  121. else
  122. {
  123. nStartIndex = 0;
  124. nNewBootpEntrySize += sizeof(WCHAR); // for the entire string terminator
  125. nNewBootpTableLength += sizeof(WCHAR);
  126. pNewBootpTable = (WCHAR *) malloc(nNewBootpEntrySize);
  127. }
  128. if (pNewBootpTable == NULL)
  129. return ERROR_NOT_ENOUGH_MEMORY;
  130. // format the new entry
  131. CString strNewEntry;
  132. strNewEntry.Format(_T("%s,%s,%s"),
  133. (LPCTSTR)m_strImageName,
  134. (LPCTSTR)m_strFileServer,
  135. (LPCTSTR)m_strFileName);
  136. // copy in the new entry
  137. CopyMemory(&pNewBootpTable[nStartIndex],
  138. strNewEntry,
  139. strNewEntry.GetLength() * sizeof(WCHAR));
  140. // set the null terminator for this entry and the entire list
  141. pNewBootpTable[(nNewBootpTableLength/sizeof(WCHAR)) - 2] = '\0';
  142. pNewBootpTable[(nNewBootpTableLength/sizeof(WCHAR)) - 1] = '\0';
  143. m_pBootpTable = pNewBootpTable;
  144. m_nBootpTableLength = nNewBootpTableLength;
  145. return ERROR_SUCCESS;
  146. }
  147. DWORD CAddBootpEntry::SetBootpTable()
  148. {
  149. DWORD dwError = 0;
  150. DHCP_SERVER_CONFIG_INFO_V4 dhcpServerInfo;
  151. ::ZeroMemory(&dhcpServerInfo, sizeof(dhcpServerInfo));
  152. dhcpServerInfo.cbBootTableString = m_nBootpTableLength;
  153. dhcpServerInfo.wszBootTableString = m_pBootpTable;
  154. BEGIN_WAIT_CURSOR;
  155. dwError = ::DhcpServerSetConfigV4(m_strServerAddress,
  156. Set_BootFileTable,
  157. &dhcpServerInfo);
  158. END_WAIT_CURSOR;
  159. if (dwError != ERROR_SUCCESS)
  160. {
  161. ::DhcpMessageBox(dwError);
  162. }
  163. return dwError;
  164. }
  165. void CAddBootpEntry::OnOK()
  166. {
  167. // If we haven't gotten the information yet, then do so now
  168. if (m_pBootpTable == NULL)
  169. {
  170. if (GetBootpTable() != ERROR_SUCCESS)
  171. return;
  172. }
  173. // Add whatever the user entered to the table
  174. if (AddBootpEntryToTable() != ERROR_SUCCESS)
  175. return;
  176. // write the table out
  177. if (SetBootpTable() != ERROR_SUCCESS)
  178. return;
  179. m_editImageName.SetWindowText(_T(""));
  180. m_editFileName.SetWindowText(_T(""));
  181. m_editFileServer.SetWindowText(_T(""));
  182. m_editImageName.SetFocus();
  183. // tell the bootp folder to update it's contents
  184. // this is the easy way to update the info... we could create
  185. // and individual entry and add it, but we'll just let the
  186. // refresh mechanism handle it
  187. CDhcpBootp * pBootp = GETHANDLER(CDhcpBootp, m_spNode);
  188. pBootp->OnRefresh(m_spNode, NULL, 0, 0, 0);
  189. }
  190. void CAddBootpEntry::OnChangeEditBootpFileName()
  191. {
  192. HandleActivation();
  193. }
  194. void CAddBootpEntry::OnChangeEditBootpFileServer()
  195. {
  196. HandleActivation();
  197. }
  198. void CAddBootpEntry::OnChangeEditBootpImageName()
  199. {
  200. HandleActivation();
  201. }
  202. void CAddBootpEntry::HandleActivation()
  203. {
  204. UpdateData();
  205. if ( (m_strImageName.GetLength() > 0) &&
  206. (m_strFileName.GetLength() > 0) &&
  207. (m_strFileServer.GetLength() > 0) )
  208. {
  209. m_buttonOk.EnableWindow(TRUE);
  210. }
  211. else
  212. {
  213. m_buttonOk.EnableWindow(FALSE);
  214. }
  215. }