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.

460 lines
12 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. dlgrecon.cpp
  7. Reconcile dialog
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "dlgrecon.h"
  12. #include "server.h"
  13. #include "scope.h"
  14. #include "mscope.h"
  15. #include "busydlg.h"
  16. /*---------------------------------------------------------------------------
  17. CReconcileWorker
  18. ---------------------------------------------------------------------------*/
  19. CReconcileWorker::CReconcileWorker(CDhcpServer * pServer, CScopeReconArray * pScopeReconArray)
  20. : m_pServer(pServer),
  21. m_pScopeReconArray(pScopeReconArray)
  22. {
  23. }
  24. CReconcileWorker::~CReconcileWorker()
  25. {
  26. }
  27. void
  28. CReconcileWorker::OnDoAction()
  29. {
  30. // are we fixing or checking?
  31. if (m_pScopeReconArray->GetSize() > 0)
  32. {
  33. // walk the scope list looking for scopes with inconsistencies
  34. for (int i = 0; i < m_pScopeReconArray->GetSize(); i++)
  35. {
  36. CScopeReconInfo ScopeReconInfo = m_pScopeReconArray->GetAt(i);
  37. // does this scope have an inconsistencies?
  38. if (ScopeReconInfo.m_pScanList->NumScanItems > 0)
  39. {
  40. if (ScopeReconInfo.m_strName.IsEmpty())
  41. {
  42. // normal scope
  43. m_dwErr = m_pServer->ScanDatabase(TRUE, &ScopeReconInfo.m_pScanList, ScopeReconInfo.m_dwScopeId);
  44. }
  45. else
  46. {
  47. // multicast scope
  48. m_dwErr = m_pServer->ScanDatabase(TRUE, &ScopeReconInfo.m_pScanList, (LPWSTR) (LPCTSTR) ScopeReconInfo.m_strName);
  49. }
  50. }
  51. }
  52. }
  53. else
  54. {
  55. // are we checking all of the scopes?
  56. if (m_fReconcileAll)
  57. {
  58. // get list of all scopes, mscopes and check each one.
  59. CheckAllScopes();
  60. }
  61. else
  62. {
  63. // we are only checking one scope, info is provided
  64. m_dwErr = ScanScope(m_strName, m_dwScopeId);
  65. }
  66. }
  67. }
  68. void
  69. CReconcileWorker::CheckAllScopes()
  70. {
  71. LARGE_INTEGER liVersion;
  72. m_pServer->GetVersion(liVersion);
  73. if (liVersion.QuadPart >= DHCP_NT5_VERSION)
  74. {
  75. CheckMScopes();
  76. }
  77. // now check all other scopes
  78. CheckScopes();
  79. }
  80. void
  81. CReconcileWorker::CheckMScopes()
  82. {
  83. DWORD dwError = ERROR_MORE_DATA;
  84. DWORD dwElementsRead = 0, dwElementsTotal = 0;
  85. LPDHCP_MSCOPE_TABLE pMScopeTable = NULL;
  86. DHCP_RESUME_HANDLE resumeHandle;
  87. //
  88. // for this server, enumerate all of it's subnets
  89. //
  90. while (dwError == ERROR_MORE_DATA)
  91. {
  92. dwError = ::DhcpEnumMScopes((LPWSTR) m_pServer->GetIpAddress(),
  93. &resumeHandle,
  94. -1,
  95. &pMScopeTable,
  96. &dwElementsRead,
  97. &dwElementsTotal);
  98. if (dwElementsRead && dwElementsTotal && pMScopeTable)
  99. {
  100. //
  101. // loop through all of the subnets that were returned
  102. //
  103. for (DWORD i = 0; i < pMScopeTable->NumElements; i++)
  104. {
  105. CString strName = pMScopeTable->pMScopeNames[i];
  106. DWORD err = ScanScope(strName, 0);
  107. if (err != ERROR_SUCCESS)
  108. {
  109. dwError = err;
  110. break;
  111. }
  112. }
  113. //
  114. // Free up the RPC memory
  115. //
  116. ::DhcpRpcFreeMemory(pMScopeTable);
  117. dwElementsRead = 0;
  118. dwElementsTotal = 0;
  119. pMScopeTable = NULL;
  120. }
  121. }
  122. if (dwError != ERROR_NO_MORE_ITEMS &&
  123. dwError != ERROR_SUCCESS &&
  124. dwError != ERROR_MORE_DATA)
  125. {
  126. m_dwErr = dwError;
  127. }
  128. else
  129. {
  130. m_dwErr = ERROR_SUCCESS;
  131. }
  132. }
  133. void
  134. CReconcileWorker::CheckScopes()
  135. {
  136. DWORD dwError = ERROR_MORE_DATA;
  137. DWORD dwElementsRead = 0, dwElementsTotal = 0;
  138. LPDHCP_IP_ARRAY pdhcpIpArray = NULL;
  139. DHCP_RESUME_HANDLE resumeHandle;
  140. //
  141. // for this server, enumerate all of it's subnets
  142. //
  143. while (dwError == ERROR_MORE_DATA)
  144. {
  145. dwError = ::DhcpEnumSubnets((LPWSTR) m_pServer->GetIpAddress(),
  146. &resumeHandle,
  147. -1,
  148. &pdhcpIpArray,
  149. &dwElementsRead,
  150. &dwElementsTotal);
  151. if (dwElementsRead && dwElementsTotal && pdhcpIpArray)
  152. {
  153. for (DWORD i = 0; i < pdhcpIpArray->NumElements; i++)
  154. {
  155. // check this scope
  156. CString strEmpty;
  157. DWORD err = ScanScope(strEmpty, pdhcpIpArray->Elements[i]);
  158. if (err != ERROR_SUCCESS)
  159. {
  160. dwError = err;
  161. break;
  162. }
  163. }
  164. //
  165. // Free up the RPC memory
  166. //
  167. ::DhcpRpcFreeMemory(pdhcpIpArray);
  168. dwElementsRead = 0;
  169. dwElementsTotal = 0;
  170. pdhcpIpArray = NULL;
  171. }
  172. }
  173. if (dwError != ERROR_NO_MORE_ITEMS &&
  174. dwError != ERROR_SUCCESS &&
  175. dwError != ERROR_MORE_DATA)
  176. {
  177. m_dwErr = dwError;
  178. }
  179. else
  180. {
  181. m_dwErr = ERROR_SUCCESS;
  182. }
  183. }
  184. DWORD
  185. CReconcileWorker::ScanScope(CString & strName, DWORD dwScopeId)
  186. {
  187. DWORD err = 0;
  188. CScopeReconInfo ScopeReconInfo;
  189. ScopeReconInfo.m_dwScopeId = dwScopeId;
  190. ScopeReconInfo.m_strName = strName;
  191. // check the scope. If the name is empty then is is a normal scope
  192. // otherwise it is a multicast scope
  193. err = (strName.IsEmpty()) ? m_pServer->ScanDatabase(FALSE, &ScopeReconInfo.m_pScanList, ScopeReconInfo.m_dwScopeId) :
  194. m_pServer->ScanDatabase(FALSE, &ScopeReconInfo.m_pScanList, (LPWSTR) (LPCTSTR) ScopeReconInfo.m_strName);
  195. if (err == ERROR_SUCCESS)
  196. {
  197. m_pScopeReconArray->Add(ScopeReconInfo);
  198. }
  199. return err;
  200. }
  201. /////////////////////////////////////////////////////////////////////////////
  202. // CReconcileDlg dialog
  203. CReconcileDlg::CReconcileDlg
  204. (
  205. ITFSNode * pServerNode,
  206. BOOL fReconcileAll,
  207. CWnd* pParent /*=NULL*/
  208. )
  209. : CBaseDialog(CReconcileDlg::IDD, pParent),
  210. m_bListBuilt(FALSE),
  211. m_bMulticast(FALSE),
  212. m_fReconcileAll(fReconcileAll)
  213. {
  214. //{{AFX_DATA_INIT(CReconcileDlg)
  215. //}}AFX_DATA_INIT
  216. m_spNode.Set(pServerNode);
  217. }
  218. void
  219. CReconcileDlg::DoDataExchange(CDataExchange* pDX)
  220. {
  221. CBaseDialog::DoDataExchange(pDX);
  222. //{{AFX_DATA_MAP(CReconcileDlg)
  223. DDX_Control(pDX, IDC_LIST_RECONCILE_IP_ADDRESSES, m_listctrlAddresses);
  224. //}}AFX_DATA_MAP
  225. }
  226. BEGIN_MESSAGE_MAP(CReconcileDlg, CBaseDialog)
  227. //{{AFX_MSG_MAP(CReconcileDlg)
  228. ON_WM_DESTROY()
  229. //}}AFX_MSG_MAP
  230. END_MESSAGE_MAP()
  231. /////////////////////////////////////////////////////////////////////////////
  232. // CReconcileDlg message handlers
  233. BOOL
  234. CReconcileDlg::OnInitDialog()
  235. {
  236. CBaseDialog::OnInitDialog();
  237. if (m_fReconcileAll)
  238. {
  239. CString strText;
  240. // set the dialog title
  241. strText.LoadString(IDS_RECONCILE_ALL_SCOPES_TITLE);
  242. SetWindowText(strText);
  243. }
  244. // setup the listctrl
  245. CString strTemp;
  246. // add the scope column
  247. strTemp.LoadString(IDS_SCOPE_FOLDER);
  248. m_listctrlAddresses.InsertColumn(0, strTemp, LVCFMT_LEFT, 150);
  249. // add the address column
  250. strTemp.LoadString(IDS_IP_ADDRESS);
  251. m_listctrlAddresses.InsertColumn(1, strTemp, LVCFMT_LEFT, 150);
  252. SetOkButton(m_bListBuilt);
  253. return TRUE; // return TRUE unless you set the focus to a control
  254. }
  255. void CReconcileDlg::SetOkButton(BOOL bListBuilt)
  256. {
  257. CWnd * pWnd = GetDlgItem(IDOK);
  258. CString strButton;
  259. if (bListBuilt)
  260. {
  261. strButton.LoadString(IDS_RECONCILE_DATABASE);
  262. }
  263. else
  264. {
  265. strButton.LoadString(IDS_CHECK_DATABASE);
  266. }
  267. pWnd->SetWindowText(strButton);
  268. }
  269. void CReconcileDlg::OnOK()
  270. {
  271. DWORD err = 0;
  272. CDhcpScope * pScope;
  273. CDhcpMScope * pMScope;
  274. CDhcpServer * pServer;
  275. if (m_fReconcileAll)
  276. {
  277. pServer = GETHANDLER(CDhcpServer, m_spNode);
  278. }
  279. else
  280. {
  281. if (m_bMulticast)
  282. {
  283. pMScope = GETHANDLER(CDhcpMScope, m_spNode);
  284. pServer = pMScope->GetServerObject();
  285. }
  286. else
  287. {
  288. pScope = GETHANDLER(CDhcpScope, m_spNode);
  289. pServer = pScope->GetServerObject();
  290. }
  291. }
  292. if (m_bListBuilt)
  293. {
  294. // we've built a list of inconsistencies. Tell the
  295. // dhcp server to reconcile them.
  296. //
  297. CReconcileWorker * pWorker = new CReconcileWorker(pServer, &m_ScopeReconArray);
  298. CLongOperationDialog dlgBusy(pWorker, IDR_SEARCH_AVI);
  299. dlgBusy.LoadTitleString(IDS_SNAPIN_DESC);
  300. dlgBusy.LoadDescriptionString(IDS_FIXING_SCOPES);
  301. dlgBusy.DoModal();
  302. if (pWorker->GetError() != ERROR_SUCCESS)
  303. {
  304. ::DhcpMessageBox(pWorker->GetError());
  305. }
  306. else
  307. {
  308. m_bListBuilt = FALSE;
  309. m_listctrlAddresses.DeleteAllItems();
  310. SetOkButton(m_bListBuilt);
  311. }
  312. }
  313. else
  314. {
  315. //
  316. // First we scan the whole database to see if
  317. // there are IP addresses that need to be resolved.
  318. //
  319. m_listctrlAddresses.DeleteAllItems();
  320. m_ScopeReconArray.RemoveAll();
  321. CReconcileWorker * pWorker = new CReconcileWorker(pServer, &m_ScopeReconArray);
  322. CLongOperationDialog dlgBusy(pWorker, IDR_SEARCH_AVI);
  323. dlgBusy.LoadTitleString(IDS_SNAPIN_DESC);
  324. dlgBusy.LoadDescriptionString(IDS_CHECKING_SCOPES);
  325. pWorker->m_fReconcileAll = m_fReconcileAll;
  326. pWorker->m_fMulticast = m_bMulticast;
  327. if (!m_fReconcileAll)
  328. {
  329. if (m_bMulticast)
  330. {
  331. pWorker->m_strName = pMScope->GetName();
  332. }
  333. else
  334. {
  335. pWorker->m_dwScopeId = pScope->GetAddress();
  336. }
  337. }
  338. dlgBusy.DoModal();
  339. if (pWorker->GetError() != ERROR_SUCCESS)
  340. {
  341. ::DhcpMessageBox(pWorker->GetError());
  342. return;
  343. }
  344. // walk the list and build the display
  345. for (int i = 0; i < m_ScopeReconArray.GetSize(); i++)
  346. {
  347. if (m_ScopeReconArray[i].m_pScanList->NumScanItems > 0)
  348. {
  349. //
  350. // There are items to be reconciled.
  351. // Present the list of ip addresses
  352. // that didn't match, and let
  353. // the user decide to add them
  354. // or not.
  355. //
  356. AddItemToList(m_ScopeReconArray[i]);
  357. m_bListBuilt = TRUE;
  358. SetOkButton(m_bListBuilt);
  359. }
  360. }
  361. if (!m_bListBuilt)
  362. {
  363. AfxMessageBox(IDS_MSG_NO_RECONCILE, MB_ICONINFORMATION);
  364. }
  365. }
  366. //CBaseDialog::OnOK();
  367. }
  368. void
  369. CReconcileDlg::AddItemToList(CScopeReconInfo & scopeReconInfo)
  370. {
  371. CString strScope;
  372. CString strAddress;
  373. int nItem = 0;
  374. // get the scope string
  375. if (scopeReconInfo.m_strName.IsEmpty())
  376. {
  377. // normal scope
  378. ::UtilCvtIpAddrToWstr(scopeReconInfo.m_dwScopeId, &strScope);
  379. }
  380. else
  381. {
  382. // multicast scope
  383. strScope = scopeReconInfo.m_strName;
  384. }
  385. // convert the inconsistent address
  386. for (DWORD j = 0; j < scopeReconInfo.m_pScanList->NumScanItems; j++)
  387. {
  388. ::UtilCvtIpAddrToWstr(scopeReconInfo.m_pScanList->ScanItems[j].IpAddress, &strAddress);
  389. nItem = m_listctrlAddresses.InsertItem(nItem, strScope);
  390. m_listctrlAddresses.SetItemText(nItem, 1, strAddress);
  391. }
  392. }