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.

4786 lines
129 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. actreg.cpp
  7. WINS active registrations node information.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "nodes.h"
  12. #include "actreg.h"
  13. #include "server.h"
  14. #include "Queryobj.h"
  15. #include "statmapp.h"
  16. #include "fndrcdlg.h"
  17. #include <string.h>
  18. #include "pushtrig.h"
  19. #include "tregkey.h"
  20. #include "chkrgdlg.h"
  21. #include "dynrecpp.h"
  22. #include "vrfysrv.h"
  23. #include "delrcdlg.h"
  24. #include "delowner.h"
  25. #include "cprogdlg.h"
  26. #include "loadrecs.h"
  27. #include "verify.h"
  28. WORD gwUnicodeHeader = 0xFEFF;
  29. #define INFINITE_EXPIRATION 0x7FFFFFFF
  30. #define BADNAME_CHAR _T('-') // This char is substituted for bad characters
  31. // NetBIOS names.
  32. UINT guActregMessageStrings[] =
  33. {
  34. IDS_ACTREG_MESSAGE_BODY1,
  35. IDS_ACTREG_MESSAGE_BODY2,
  36. IDS_ACTREG_MESSAGE_BODY3,
  37. IDS_ACTREG_MESSAGE_BODY4,
  38. -1
  39. };
  40. BOOL
  41. WinsIsPrint(char * pChar)
  42. {
  43. WORD charType;
  44. // isprint isn't working for thai characters, so use the GetStringType
  45. // API and figure it out ourselves.
  46. BOOL fRet = GetStringTypeA(LOCALE_SYSTEM_DEFAULT, CT_CTYPE1, pChar, 1, &charType);
  47. if (!fRet)
  48. return 0;
  49. return !(charType & C1_CNTRL) ? 1 : 0;
  50. }
  51. /*---------------------------------------------------------------------------
  52. class CSortWorker
  53. ---------------------------------------------------------------------------*/
  54. CSortWorker::CSortWorker(IWinsDatabase * pCurrentDatabase,
  55. int nColumn,
  56. DWORD dwSortOptions)
  57. {
  58. m_pCurrentDatabase = pCurrentDatabase;
  59. m_nColumn = nColumn;
  60. m_dwSortOptions = dwSortOptions;
  61. }
  62. CSortWorker::~CSortWorker()
  63. {
  64. }
  65. void
  66. CSortWorker::OnDoAction()
  67. {
  68. #ifdef DEBUG
  69. CString strType;
  70. CTime timeStart, timeFinish;
  71. timeStart = CTime::GetCurrentTime();
  72. #endif
  73. WINSDB_SORT_TYPE uSortType = WINSDB_SORT_BY_NAME;
  74. switch (m_nColumn)
  75. {
  76. case ACTREG_COL_NAME:
  77. uSortType = WINSDB_SORT_BY_NAME;
  78. break;
  79. case ACTREG_COL_TYPE:
  80. uSortType = WINSDB_SORT_BY_TYPE;
  81. break;
  82. case ACTREG_COL_IPADDRESS:
  83. uSortType = WINSDB_SORT_BY_IP;
  84. break;
  85. case ACTREG_COL_STATE:
  86. uSortType = WINSDB_SORT_BY_STATE;
  87. break;
  88. case ACTREG_COL_STATIC:
  89. uSortType = WINSDB_SORT_BY_STATIC;
  90. break;
  91. case ACTREG_COL_VERSION:
  92. uSortType = WINSDB_SORT_BY_VERSION;
  93. break;
  94. case ACTREG_COL_EXPIRATION:
  95. uSortType = WINSDB_SORT_BY_EXPIRATION;
  96. break;
  97. case ACTREG_COL_OWNER:
  98. uSortType = WINSDB_SORT_BY_OWNER;
  99. break;
  100. }
  101. BEGIN_WAIT_CURSOR
  102. m_pCurrentDatabase->Sort(uSortType, m_dwSortOptions);
  103. END_WAIT_CURSOR
  104. #ifdef DEBUG
  105. timeFinish = CTime::GetCurrentTime();
  106. CTimeSpan timeDelta = timeFinish - timeStart;
  107. CString str = timeDelta.Format(_T("%H:%M:%S"));
  108. Trace2("Record Sorting for the column: %d, total time %s\n",
  109. uSortType, str);
  110. #endif
  111. }
  112. /*---------------------------------------------------------------------------
  113. CActiveRegistrationsHandler::CActiveRegistrationsHandler
  114. Description
  115. Author: EricDav
  116. ---------------------------------------------------------------------------*/
  117. CActiveRegistrationsHandler::CActiveRegistrationsHandler(ITFSComponentData *pCompData)
  118. : CMTWinsHandler(pCompData), m_dlgLoadRecords(IDS_VIEW_RECORDS)
  119. {
  120. m_winsdbState = WINSDB_NORMAL;
  121. m_bExpanded = FALSE;
  122. m_pCurrentDatabase = NULL;
  123. m_fFindNameOrIP = TRUE;
  124. m_NonBlocking = 1;
  125. m_pServerInfoArray = NULL;
  126. m_fLoadedOnce = FALSE;
  127. m_fFindLoaded = FALSE;
  128. m_fDbLoaded = FALSE;
  129. m_fForceReload = TRUE;
  130. }
  131. /*---------------------------------------------------------------------------
  132. CActiveRegistrationsHandler::~CActiveRegistrationsHandler
  133. Description
  134. ---------------------------------------------------------------------------*/
  135. CActiveRegistrationsHandler::~CActiveRegistrationsHandler()
  136. {
  137. }
  138. /*---------------------------------------------------------------------------
  139. CActiveRegistrationsHandler::DestroyHandler
  140. Release and pointers we have here
  141. Author: EricDav
  142. ----------------------------------------------------------------------------*/
  143. HRESULT
  144. CActiveRegistrationsHandler::DestroyHandler
  145. (
  146. ITFSNode * pNode
  147. )
  148. {
  149. m_spServerNode.Set(NULL);
  150. return hrOK;
  151. }
  152. /*!--------------------------------------------------------------------------
  153. CActiveRegistrationsHandler::InitializeNode
  154. Initializes node specific data
  155. ---------------------------------------------------------------------------*/
  156. HRESULT
  157. CActiveRegistrationsHandler::InitializeNode
  158. (
  159. ITFSNode * pNode
  160. )
  161. {
  162. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  163. HRESULT hr = hrOK;
  164. CString strTemp;
  165. m_strActiveReg.LoadString(IDS_ACTIVEREG);
  166. SetDisplayName(m_strActiveReg);
  167. m_strDesp.LoadString(IDS_ACTIVEREG_DISC);
  168. // Make the node immediately visible
  169. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  170. pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
  171. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
  172. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  173. pNode->SetData(TFS_DATA_TYPE, WINSSNAP_ACTIVE_REGISTRATIONS);
  174. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  175. SetColumnStringIDs(&aColumns[WINSSNAP_ACTIVE_REGISTRATIONS][0]);
  176. SetColumnWidths(&aColumnWidths[WINSSNAP_ACTIVE_REGISTRATIONS][0]);
  177. if (g_strStaticTypeUnique.IsEmpty())
  178. {
  179. g_strStaticTypeUnique.LoadString(IDS_STATIC_RECORD_TYPE_UNIQUE);
  180. g_strStaticTypeDomainName.LoadString(IDS_STATIC_RECORD_TYPE_DOMAIN_NAME);
  181. g_strStaticTypeMultihomed.LoadString(IDS_STATIC_RECORD_TYPE_MULTIHOMED);
  182. g_strStaticTypeGroup.LoadString(IDS_STATIC_RECORD_TYPE_GROUP);
  183. g_strStaticTypeInternetGroup.LoadString(IDS_STATIC_RECORD_TYPE_INTERNET_GROUP);
  184. g_strStaticTypeUnknown.LoadString(IDS_STATIC_RECORD_TYPE_UNKNOWN);
  185. }
  186. return hr;
  187. }
  188. /*---------------------------------------------------------------------------
  189. CActiveRegistrationsHandler::OnCreateNodeId2
  190. Returns a unique string for this node
  191. Author: EricDav
  192. ---------------------------------------------------------------------------*/
  193. HRESULT CActiveRegistrationsHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  194. {
  195. const GUID * pGuid = pNode->GetNodeType();
  196. CString strGuid;
  197. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  198. strGuid.ReleaseBuffer();
  199. SPITFSNode spServerNode;
  200. pNode->GetParent(&spServerNode);
  201. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  202. strId = pServer->m_strServerAddress + strGuid;
  203. return hrOK;
  204. }
  205. /*---------------------------------------------------------------------------
  206. Overridden base handler functions
  207. ---------------------------------------------------------------------------*/
  208. /*!--------------------------------------------------------------------------
  209. CActiveRegistrationsHandler::GetString
  210. Implementation of ITFSNodeHandler::GetString
  211. Author: KennT
  212. ---------------------------------------------------------------------------*/
  213. STDMETHODIMP_(LPCTSTR)
  214. CActiveRegistrationsHandler::GetString
  215. (
  216. ITFSNode * pNode,
  217. int nCol
  218. )
  219. {
  220. if (nCol == 0 || nCol == -1)
  221. {
  222. return GetDisplayName();
  223. }
  224. else
  225. if (nCol ==1)
  226. {
  227. return m_strDesp;
  228. }
  229. else
  230. {
  231. return NULL;
  232. }
  233. }
  234. /*---------------------------------------------------------------------------
  235. CActiveRegistrationsHandler::OnExpand
  236. Description
  237. ---------------------------------------------------------------------------*/
  238. HRESULT
  239. CActiveRegistrationsHandler::OnExpand
  240. (
  241. ITFSNode * pNode,
  242. LPDATAOBJECT pDataObject,
  243. DWORD dwType,
  244. LPARAM arg,
  245. LPARAM param
  246. )
  247. {
  248. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  249. HRESULT hr = hrOK;
  250. SPITFSNode spNode;
  251. SPITFSNodeHandler spHandler;
  252. ITFSQueryObject * pQuery = NULL;
  253. CString strIP;
  254. DWORD dwIP;
  255. CString strMachineName;
  256. SPITFSNode spServerNode;
  257. pNode->GetParent(&spServerNode);
  258. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  259. // get the config info for later
  260. m_Config = pServer->GetConfig();
  261. m_RecList.RemoveAll();
  262. if (m_bExpanded)
  263. {
  264. return hr;
  265. }
  266. strMachineName = _T("\\\\") + pServer->GetServerAddress();
  267. // load the name type mapping from the registry
  268. m_NameTypeMap.SetMachineName(strMachineName);
  269. m_NameTypeMap.Load();
  270. // start the database download for the surrent owner
  271. if (!m_spWinsDatabase)
  272. {
  273. dwIP = pServer->GetServerIP();
  274. MakeIPAddress(dwIP, strIP);
  275. m_dlgLoadRecords.ResetFiltering();
  276. CORg(CreateWinsDatabase(strIP, strIP, &m_spWinsDatabase));
  277. // set the owner to the current owner
  278. m_spWinsDatabase->SetApiInfo(
  279. dwIP,
  280. NULL,
  281. FALSE);
  282. }
  283. m_bExpanded = TRUE;
  284. COM_PROTECT_ERROR_LABEL;
  285. return hr;
  286. }
  287. /*---------------------------------------------------------------------------
  288. CWinsServerHandler::OnResultRefresh
  289. Refreshes the data realting to the server
  290. Author: v-shubk
  291. ---------------------------------------------------------------------------*/
  292. HRESULT
  293. CActiveRegistrationsHandler::OnResultRefresh
  294. (
  295. ITFSComponent * pComponent,
  296. LPDATAOBJECT pDataObject,
  297. MMC_COOKIE cookie,
  298. LPARAM arg,
  299. LPARAM lParam
  300. )
  301. {
  302. HRESULT hr = hrOK;
  303. SPITFSNode spNode;
  304. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  305. // get the stae of the databse if not normal, ie in the loading or filtering state
  306. // don't let refresh
  307. if (m_winsdbState != WINSDB_NORMAL)
  308. {
  309. return hrOK;
  310. }
  311. RefreshResults(spNode);
  312. Error:
  313. return hr;
  314. }
  315. /*---------------------------------------------------------------------------
  316. CActiveRegistrationsHandler::OnCreateQuery
  317. Description
  318. Author: v-shubk
  319. ---------------------------------------------------------------------------*/
  320. ITFSQueryObject *
  321. CActiveRegistrationsHandler::OnCreateQuery(ITFSNode * pNode)
  322. {
  323. CNodeTimerQueryObject * pQObj = new CNodeTimerQueryObject();
  324. pQObj->SetTimerInterval(2000);
  325. return pQObj;
  326. }
  327. /*---------------------------------------------------------------------------
  328. CActiveRegistrationsHandler::OnHaveData
  329. Description
  330. Author: EricDav
  331. ---------------------------------------------------------------------------*/
  332. void
  333. CActiveRegistrationsHandler::OnHaveData
  334. (
  335. ITFSNode * pParentNode,
  336. LPARAM Data,
  337. LPARAM Type
  338. )
  339. {
  340. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  341. // This is how we get non-node data back from the background thread.
  342. HRESULT hr = hrOK;
  343. WINSDB_STATE uState;
  344. COM_PROTECT_TRY
  345. {
  346. if (Type == QDATA_TIMER)
  347. {
  348. BOOL bDone;
  349. m_spWinsDatabase->GetCurrentState(&uState);
  350. bDone = (m_winsdbState == WINSDB_LOADING && uState != WINSDB_LOADING) ||
  351. (m_winsdbState == WINSDB_FILTERING && uState != WINSDB_LOADING);
  352. // if records per owner are downloaded, clear and redraw the
  353. // items as the records are inserted, rather than being added.
  354. //if (TRUE /*m_dwOwnerFilter != -1*/)
  355. //{
  356. // UpdateCurrentView(pParentNode);
  357. //}
  358. // call into the WinsDatbase object and check the count.
  359. // if we need to update call..UpdateAllViews
  360. UpdateListboxCount(pParentNode);
  361. UpdateCurrentView(pParentNode);
  362. if (m_nState != loading)
  363. {
  364. m_nState = loading;
  365. OnChangeState(pParentNode);
  366. }
  367. // take care of the tomer in case of the filetr records case
  368. if (bDone)
  369. {
  370. Trace0("ActiveRegHandler::OnHaveData - Done loading DB\n");
  371. DatabaseLoadingCleanup();
  372. if ( (m_nState != loaded) &&
  373. (m_nState != unableToLoad) )
  374. {
  375. m_nState = loaded;
  376. m_dwErr = 0;
  377. OnChangeState(pParentNode);
  378. }
  379. }
  380. }
  381. }
  382. COM_PROTECT_CATCH
  383. return;
  384. }
  385. /*---------------------------------------------------------------------------
  386. CActiveRegistrationsHandler::CActiveRegistrationsHandler
  387. Description
  388. Author: v-shubk
  389. ---------------------------------------------------------------------------*/
  390. int CActiveRegistrationsHandler::GetImageIndex(BOOL bOpenImage)
  391. {
  392. int nIndex = 0;
  393. switch (m_nState)
  394. {
  395. case notLoaded:
  396. case loaded:
  397. case unableToLoad:
  398. if (bOpenImage)
  399. nIndex = ICON_IDX_ACTREG_FOLDER_OPEN;
  400. else
  401. nIndex = ICON_IDX_ACTREG_FOLDER_CLOSED;
  402. break;
  403. case loading:
  404. if (bOpenImage)
  405. nIndex = ICON_IDX_ACTREG_FOLDER_OPEN_BUSY;
  406. else
  407. nIndex = ICON_IDX_ACTREG_FOLDER_CLOSED_BUSY;
  408. break;
  409. default:
  410. ASSERT(FALSE);
  411. }
  412. return nIndex;
  413. }
  414. /*---------------------------------------------------------------------------
  415. CActiveRegistrationsHandler::OnAddMenuItems
  416. Description
  417. Author: EricDav
  418. ---------------------------------------------------------------------------*/
  419. STDMETHODIMP
  420. CActiveRegistrationsHandler::OnAddMenuItems
  421. (
  422. ITFSNode * pNode,
  423. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  424. LPDATAOBJECT lpDataObject,
  425. DATA_OBJECT_TYPES type,
  426. DWORD dwType,
  427. long * pInsertionAllowed
  428. )
  429. {
  430. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  431. HRESULT hr = S_OK;
  432. LONG lFlags = 0;
  433. CString strMenuItem;
  434. if (!m_Config.IsAdmin())
  435. {
  436. lFlags = MF_GRAYED;
  437. }
  438. if (type == CCT_SCOPE)
  439. {
  440. // these menu items go in the new menu,
  441. // only visible from scope pane
  442. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  443. {
  444. // find record
  445. //strMenuItem.LoadString(IDS_ACTIVEREG_FIND_RECORD);
  446. //hr = LoadAndAddMenuItem( pContextMenuCallback,
  447. // strMenuItem,
  448. // IDS_ACTIVEREG_FIND_RECORD,
  449. // CCM_INSERTIONPOINTID_PRIMARY_TOP,
  450. // 0 );
  451. //ASSERT( SUCCEEDED(hr) );
  452. // start database load if th state is normal
  453. if (m_winsdbState == WINSDB_NORMAL)
  454. {
  455. strMenuItem.LoadString(IDS_DATABASE_LOAD_START);
  456. hr = LoadAndAddMenuItem( pContextMenuCallback,
  457. strMenuItem,
  458. IDS_DATABASE_LOAD_START,
  459. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  460. 0 );
  461. ASSERT( SUCCEEDED(hr) );
  462. }
  463. else
  464. {
  465. strMenuItem.LoadString(IDS_DATABASE_LOAD_STOP);
  466. hr = LoadAndAddMenuItem( pContextMenuCallback,
  467. strMenuItem,
  468. IDS_DATABASE_LOAD_STOP,
  469. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  470. 0 );
  471. ASSERT( SUCCEEDED(hr) );
  472. }
  473. // separator
  474. hr = LoadAndAddMenuItem( pContextMenuCallback,
  475. strMenuItem,
  476. 0,
  477. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  478. MF_SEPARATOR);
  479. ASSERT( SUCCEEDED(hr) );
  480. // create static mapping
  481. strMenuItem.LoadString(IDS_ACTIVEREG_CREATE_STATIC_MAPPING);
  482. hr = LoadAndAddMenuItem( pContextMenuCallback,
  483. strMenuItem,
  484. IDS_ACTIVEREG_CREATE_STATIC_MAPPING,
  485. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  486. 0 );
  487. ASSERT( SUCCEEDED(hr) );
  488. // separator
  489. hr = LoadAndAddMenuItem( pContextMenuCallback,
  490. strMenuItem,
  491. 0,
  492. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  493. MF_SEPARATOR);
  494. ASSERT( SUCCEEDED(hr) );
  495. // import LMHOSTS file
  496. strMenuItem.LoadString(IDS_ACTIVEREG_IMPORT_LMHOSTS);
  497. hr = LoadAndAddMenuItem( pContextMenuCallback,
  498. strMenuItem,
  499. IDS_ACTIVEREG_IMPORT_LMHOSTS,
  500. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  501. 0 );
  502. ASSERT( SUCCEEDED(hr) );
  503. // only available to admins
  504. strMenuItem.LoadString(IDS_ACTREG_CHECK_REG_NAMES);
  505. hr = LoadAndAddMenuItem( pContextMenuCallback,
  506. strMenuItem,
  507. IDS_ACTREG_CHECK_REG_NAMES,
  508. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  509. lFlags );
  510. ASSERT( SUCCEEDED(hr) );
  511. strMenuItem.LoadString(IDS_ACTREG_DELETE_OWNER);
  512. hr = LoadAndAddMenuItem( pContextMenuCallback,
  513. strMenuItem,
  514. IDS_ACTREG_DELETE_OWNER,
  515. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  516. 0 );
  517. ASSERT( SUCCEEDED(hr) );
  518. }
  519. }
  520. return hr;
  521. }
  522. /*---------------------------------------------------------------------------
  523. CActiveRegistrationsHandler::OnCommand
  524. Description
  525. Author: EricDav
  526. ---------------------------------------------------------------------------*/
  527. STDMETHODIMP
  528. CActiveRegistrationsHandler::OnCommand
  529. (
  530. ITFSNode * pNode,
  531. long nCommandId,
  532. DATA_OBJECT_TYPES type,
  533. LPDATAOBJECT pDataObject,
  534. DWORD dwType
  535. )
  536. {
  537. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  538. HRESULT hr = S_OK;
  539. switch (nCommandId)
  540. {
  541. case IDS_ACTIVEREG_CREATE_STATIC_MAPPING:
  542. OnCreateMapping(pNode);
  543. break;
  544. case IDS_DATABASE_LOAD_START:
  545. OnDatabaseLoadStart(pNode);
  546. break;
  547. case IDS_DATABASE_LOAD_STOP:
  548. OnDatabaseLoadStop(pNode);
  549. break;
  550. case IDS_ACTIVEREG_IMPORT_LMHOSTS:
  551. OnImportLMHOSTS(pNode);
  552. break;
  553. case IDS_ACTIVEREG_EXPORT_WINSENTRIES:
  554. OnExportEntries();
  555. break;
  556. case IDS_ACTREG_CHECK_REG_NAMES:
  557. OnCheckRegNames(pNode);
  558. break;
  559. case IDS_ACTREG_DELETE_OWNER:
  560. OnDeleteOwner(pNode);
  561. break;
  562. default:
  563. break;
  564. }
  565. return hr;
  566. }
  567. /*!--------------------------------------------------------------------------
  568. CActiveRegistrationsHandler::AddMenuItems
  569. Over-ride this to add our view menu item
  570. Author: EricDav
  571. ---------------------------------------------------------------------------*/
  572. STDMETHODIMP
  573. CActiveRegistrationsHandler::AddMenuItems
  574. (
  575. ITFSComponent * pComponent,
  576. MMC_COOKIE cookie,
  577. LPDATAOBJECT pDataObject,
  578. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  579. long * pInsertionAllowed
  580. )
  581. {
  582. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  583. HRESULT hr = S_OK;
  584. CString strMenuItem;
  585. LONG lFlags = 0;
  586. // figure out if we need to pass this to the scope pane menu handler
  587. hr = HandleScopeMenus(cookie, pDataObject, pContextMenuCallback, pInsertionAllowed);
  588. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  589. {
  590. if (m_fLoadedOnce)
  591. {
  592. lFlags = MF_CHECKED|MFT_RADIOCHECK;
  593. }
  594. else
  595. {
  596. lFlags = 0;
  597. }
  598. strMenuItem.LoadString(IDS_ACTREG_SHOW_ENTIRE);
  599. hr = LoadAndAddMenuItem( pContextMenuCallback,
  600. strMenuItem,
  601. IDM_FILTER_DATABASE,
  602. CCM_INSERTIONPOINTID_PRIMARY_VIEW,
  603. lFlags);
  604. ASSERT( SUCCEEDED(hr) );
  605. }
  606. return hr;
  607. }
  608. /*!--------------------------------------------------------------------------
  609. CActiveRegistrationsHandler::Command
  610. Handles commands for the current view
  611. Author: EricDav
  612. ---------------------------------------------------------------------------*/
  613. STDMETHODIMP
  614. CActiveRegistrationsHandler::Command
  615. (
  616. ITFSComponent * pComponent,
  617. MMC_COOKIE cookie,
  618. int nCommandID,
  619. LPDATAOBJECT pDataObject
  620. )
  621. {
  622. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  623. HRESULT hr = S_OK;
  624. SPITFSNode spNode;
  625. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  626. switch (nCommandID)
  627. {
  628. case IDM_FILTER_DATABASE:
  629. if (m_fDbLoaded)
  630. {
  631. UpdateCurrentView(spNode);
  632. }
  633. else
  634. {
  635. OnDatabaseLoadStart(spNode);
  636. }
  637. break;
  638. // this may have come from the scope pane handler, so pass it up
  639. default:
  640. hr = HandleScopeCommand(cookie, nCommandID, pDataObject);
  641. break;
  642. }
  643. Error:
  644. return hr;
  645. }
  646. /*!--------------------------------------------------------------------------
  647. CActiveRegistrationsHandler::HasPropertyPages
  648. Implementation of ITFSNodeHandler::HasPropertyPages
  649. NOTE: the root node handler has to over-ride this function to
  650. handle the snapin manager property page (wizard) case!!!
  651. ---------------------------------------------------------------------------*/
  652. STDMETHODIMP
  653. CActiveRegistrationsHandler::HasPropertyPages
  654. (
  655. ITFSNode * pNode,
  656. LPDATAOBJECT pDataObject,
  657. DATA_OBJECT_TYPES type,
  658. DWORD dwType
  659. )
  660. {
  661. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  662. HRESULT hr = hrOK;
  663. if (dwType & TFS_COMPDATA_CREATE)
  664. {
  665. // This is the case where we are asked to bring up property
  666. // pages when the user is adding a new snapin. These calls
  667. // are forwarded to the root node to handle.
  668. hr = hrFalse;
  669. }
  670. else
  671. {
  672. // we have property pages in the normal case
  673. hr = hrOK;
  674. }
  675. return hr;
  676. }
  677. /*---------------------------------------------------------------------------
  678. CActiveRegistrationsHandler::CreatePropertyPages
  679. The active registrations node (scope pane) doesn't have
  680. any property pages. We should never get here.
  681. ---------------------------------------------------------------------------*/
  682. STDMETHODIMP
  683. CActiveRegistrationsHandler::CreatePropertyPages
  684. (
  685. ITFSNode * pNode,
  686. LPPROPERTYSHEETCALLBACK lpProvider,
  687. LPDATAOBJECT pDataObject,
  688. LONG_PTR handle,
  689. DWORD dwType
  690. )
  691. {
  692. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  693. // we use this to create static mappings, but we don't show it
  694. // through the properties verb. We invoke this mechanism when the
  695. // user selects create static mapping
  696. HRESULT hr = hrOK;
  697. // Object gets deleted when the page is destroyed
  698. SPIComponentData spComponentData;
  699. m_spNodeMgr->GetComponentData(&spComponentData);
  700. // show the same page as the statis mapping properties
  701. CStaticMappingProperties * pMapping =
  702. new CStaticMappingProperties (pNode,
  703. spComponentData,
  704. NULL,
  705. NULL,
  706. TRUE);
  707. pMapping->m_ppageGeneral->m_uImage = ICON_IDX_CLIENT;
  708. pMapping->CreateModelessSheet(lpProvider, handle);
  709. return hr;
  710. }
  711. /*!--------------------------------------------------------------------------
  712. CActiveRegistrationsHandler::HasPropertyPages
  713. Implementation of ITFSResultHandler::HasPropertyPages
  714. Author: KennT
  715. ---------------------------------------------------------------------------*/
  716. STDMETHODIMP
  717. CActiveRegistrationsHandler::HasPropertyPages
  718. (
  719. ITFSComponent * pComponent,
  720. MMC_COOKIE cookie,
  721. LPDATAOBJECT pDataObject
  722. )
  723. {
  724. return hrOK;
  725. }
  726. /*!--------------------------------------------------------------------------
  727. CActiveRegistrationsHandler::CreatePropertyPages
  728. Implementation of ITFSResultHandler::CreatePropertyPages
  729. Author: KennT
  730. ---------------------------------------------------------------------------*/
  731. STDMETHODIMP
  732. CActiveRegistrationsHandler::CreatePropertyPages
  733. (
  734. ITFSComponent * pComponent,
  735. MMC_COOKIE cookie,
  736. LPPROPERTYSHEETCALLBACK lpProvider,
  737. LPDATAOBJECT pDataObject,
  738. LONG_PTR handle
  739. )
  740. {
  741. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  742. HRESULT hr = hrOK;
  743. HPROPSHEETPAGE hPage;
  744. SPINTERNAL spInternal;
  745. SPIComponentData spComponentData;
  746. SPIComponent spComponent;
  747. SPITFSNode spNode;
  748. SPIResultData spResultData;
  749. int nIndex ;
  750. HROW hRowSel;
  751. WinsRecord wRecord;
  752. WinsStrRecord *pwstrRecord;
  753. int nCount;
  754. // get the resultdata interface
  755. CORg (pComponent->GetResultData(&spResultData));
  756. spInternal = ExtractInternalFormat(pDataObject);
  757. // virtual listbox notifications come to the handler of the node
  758. // that is selected. check to see if this notification is for a
  759. // virtual listbox item or the active registrations node itself.
  760. if (spInternal->HasVirtualIndex())
  761. {
  762. // we gotta do special stuff for the virtual index items
  763. m_spNodeMgr->FindNode(cookie, &spNode);
  764. CORg(spComponent.HrQuery(pComponent));
  765. Assert(spComponent);
  766. m_nSelectedIndex = spInternal->GetVirtualIndex();
  767. nIndex = m_nSelectedIndex;
  768. // if an invalid index, return
  769. m_pCurrentDatabase->GetCurrentCount(&nCount);
  770. if (nIndex < 0 || nIndex >= nCount)
  771. {
  772. return hrOK;
  773. }
  774. // get the correct data for the record selected
  775. m_spWinsDatabase->GetHRow(nIndex, &hRowSel);
  776. m_spWinsDatabase->GetData(hRowSel, &wRecord);
  777. GetRecordOwner(spNode, &wRecord);
  778. // put up different page depending on wheter static or dynamic
  779. if (wRecord.dwState & WINSDB_REC_STATIC)
  780. {
  781. m_CurrentRecord = wRecord;
  782. CStaticMappingProperties * pStat =
  783. new CStaticMappingProperties(spNode,
  784. spComponent,
  785. NULL,
  786. &wRecord,
  787. FALSE);
  788. pStat->m_ppageGeneral->m_uImage = GetVirtualImage(nIndex);
  789. Assert(lpProvider != NULL);
  790. return pStat->CreateModelessSheet(lpProvider, handle);
  791. }
  792. // dynamic case
  793. else
  794. {
  795. CDynamicMappingProperties *pDyn =
  796. new CDynamicMappingProperties(spNode,
  797. spComponent,
  798. NULL,
  799. &wRecord);
  800. pDyn->m_pageGeneral.m_uImage = GetVirtualImage(nIndex);
  801. Assert(lpProvider != NULL);
  802. return pDyn->CreateModelessSheet(lpProvider, handle);
  803. }
  804. }
  805. else
  806. {
  807. Assert(FALSE);
  808. }
  809. COM_PROTECT_ERROR_LABEL;
  810. return hr;
  811. }
  812. /*---------------------------------------------------------------------------
  813. CActiveRegistrationsHandler::OnPropertyChange
  814. Description
  815. Author: EricDav
  816. ---------------------------------------------------------------------------*/
  817. HRESULT
  818. CActiveRegistrationsHandler::OnPropertyChange
  819. (
  820. ITFSNode * pNode,
  821. LPDATAOBJECT pDataobject,
  822. DWORD dwType,
  823. LPARAM arg,
  824. LPARAM lParam
  825. )
  826. {
  827. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  828. CStaticMappingProperties * pProp =
  829. reinterpret_cast<CStaticMappingProperties *>(lParam);
  830. LONG_PTR changeMask = 0;
  831. // tell the property page to do whatever now that we are back on the
  832. // main thread
  833. pProp->OnPropertyChange(TRUE, &changeMask);
  834. pProp->AcknowledgeNotify();
  835. // refresh the result pane
  836. if (changeMask)
  837. UpdateListboxCount(pNode);
  838. return hrOK;
  839. }
  840. /*---------------------------------------------------------------------------
  841. CActiveRegistrationsHandler::OnResultPropertyChange
  842. Description
  843. Author: EricDav
  844. ---------------------------------------------------------------------------*/
  845. HRESULT
  846. CActiveRegistrationsHandler::OnResultPropertyChange
  847. (
  848. ITFSComponent * pComponent,
  849. LPDATAOBJECT pDataObject,
  850. MMC_COOKIE cookie,
  851. LPARAM arg,
  852. LPARAM param
  853. )
  854. {
  855. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  856. HRESULT hr = hrOK;
  857. SPINTERNAL spInternal;
  858. SPITFSNode spNode;
  859. m_spNodeMgr->FindNode(cookie, &spNode);
  860. CStaticMappingProperties * pProp = reinterpret_cast<CStaticMappingProperties *>(param);
  861. LONG_PTR changeMask = 0;
  862. // tell the property page to do whatever now that we are back on the
  863. // main thread
  864. pProp->SetComponent(pComponent);
  865. pProp->OnPropertyChange(TRUE, &changeMask);
  866. pProp->AcknowledgeNotify();
  867. // refresh the result pane
  868. if (changeMask)
  869. UpdateListboxCount(spNode);
  870. return hr;
  871. }
  872. /*---------------------------------------------------------------------------
  873. CActiveRegistrationsHandler::OnResultDelete
  874. Description
  875. Author: EricDav
  876. ---------------------------------------------------------------------------*/
  877. HRESULT
  878. CActiveRegistrationsHandler::OnResultDelete
  879. (
  880. ITFSComponent * pComponent,
  881. LPDATAOBJECT pDataObject,
  882. MMC_COOKIE cookie,
  883. LPARAM arg,
  884. LPARAM lParam
  885. )
  886. {
  887. HRESULT hr = hrOK;
  888. Trace0("CActiveRegistrationsHandler::OnResultDelete received\n");
  889. SPINTERNAL spInternal;
  890. spInternal = ExtractInternalFormat(pDataObject);
  891. // virtual listbox notifications come to the handler of the node
  892. // that is selected. check to see if this notification is for a
  893. // virtual listbox item or the active registrations node itself.
  894. if (spInternal->HasVirtualIndex())
  895. {
  896. // we gotta do special stuff for the virtual index items
  897. DeleteRegistration(pComponent, spInternal->GetVirtualIndex());
  898. }
  899. else
  900. {
  901. // just call the base class to update verbs for the
  902. CMTWinsHandler::OnResultDelete(pComponent,
  903. pDataObject,
  904. cookie,
  905. arg,
  906. lParam);
  907. }
  908. return hr;
  909. }
  910. /*!--------------------------------------------------------------------------
  911. CActiveRegistrationsHandler::OnResultSelect
  912. Handles the MMCN_SELECT notifcation
  913. Author: EricDav
  914. ---------------------------------------------------------------------------*/
  915. HRESULT
  916. CActiveRegistrationsHandler::OnResultSelect
  917. (
  918. ITFSComponent * pComponent,
  919. LPDATAOBJECT pDataObject,
  920. MMC_COOKIE cookie,
  921. LPARAM arg,
  922. LPARAM lParam
  923. )
  924. {
  925. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  926. HRESULT hr = hrOK;
  927. int i;
  928. WINSDB_STATE uState = WINSDB_LOADING;
  929. SPINTERNAL spInternal;
  930. SPIConsoleVerb spConsoleVerb;
  931. SPIConsole spConsole;
  932. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  933. SPITFSNode spNode;
  934. // show the result pane message
  935. if (!m_fLoadedOnce)
  936. {
  937. CString strTitle, strBody, strTemp;
  938. m_spResultNodeMgr->FindNode(cookie, &spNode);
  939. strTitle.LoadString(IDS_ACTREG_MESSAGE_TITLE);
  940. for (i = 0; ; i++)
  941. {
  942. if (guActregMessageStrings[i] == -1)
  943. break;
  944. strTemp.LoadString(guActregMessageStrings[i]);
  945. strBody += strTemp;
  946. }
  947. ShowMessage(spNode, strTitle, strBody, Icon_Information);
  948. }
  949. else
  950. {
  951. ULARGE_INTEGER data, *pData;
  952. // fill in the result pane
  953. if (m_spWinsDatabase)
  954. {
  955. m_spWinsDatabase->GetCurrentState(&uState);
  956. // check to see if we are done
  957. if (m_winsdbState == WINSDB_LOADING &&
  958. uState != WINSDB_LOADING)
  959. {
  960. Trace0("ActiveRegHandler::OnResultSelect - Done loading DB\n");
  961. DatabaseLoadingCleanup();
  962. }
  963. }
  964. if (m_pCurrentDatabase)
  965. {
  966. // Get the count from the database
  967. CORg (m_pCurrentDatabase->GetCurrentScanned((int*)&data.LowPart));
  968. CORg (m_pCurrentDatabase->GetCurrentCount((int*)&data.HighPart));
  969. pData = &data;
  970. }
  971. else
  972. {
  973. pData = NULL;
  974. }
  975. // now notify the virtual listbox
  976. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  977. CORg ( spConsole->UpdateAllViews(pDataObject,
  978. (LPARAM)pData,
  979. RESULT_PANE_SET_VIRTUAL_LB_SIZE) );
  980. }
  981. // now update the verbs...
  982. spInternal = ExtractInternalFormat(pDataObject);
  983. Assert(spInternal);
  984. // virtual listbox notifications come to the handler of the node
  985. // that is selected.check to see if this notification is for a
  986. // virtual listbox item or the active registrations node itself.
  987. if (spInternal->HasVirtualIndex())
  988. {
  989. // is this a multiselect?
  990. BOOL fMultiSelect = spInternal->m_cookie == MMC_MULTI_SELECT_COOKIE ? TRUE : FALSE;
  991. if (!fMultiSelect)
  992. {
  993. // when something is selected in the result pane we want the default verb to be properties
  994. m_verbDefault = MMC_VERB_PROPERTIES;
  995. }
  996. else
  997. {
  998. // we don't support multi-select properties
  999. m_verbDefault = MMC_VERB_NONE;
  1000. }
  1001. // we gotta do special stuff for the virtual index items
  1002. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  1003. UpdateConsoleVerbs(spConsoleVerb, WINSSNAP_REGISTRATION, fMultiSelect);
  1004. }
  1005. else
  1006. {
  1007. // when the active registrations node itself is selected, default should be open
  1008. m_verbDefault = MMC_VERB_OPEN;
  1009. g_ConsoleVerbStates[WINSSNAP_ACTIVE_REGISTRATIONS][6] = ENABLED;
  1010. // just call the base class to update verbs for the
  1011. CMTWinsHandler::OnResultSelect(pComponent,
  1012. pDataObject,
  1013. cookie,
  1014. arg,
  1015. lParam);
  1016. }
  1017. COM_PROTECT_ERROR_LABEL;
  1018. return hr;
  1019. }
  1020. /*---------------------------------------------------------------------------
  1021. CActiveRegistrationsHandler::DatabaseLoadingCleanup
  1022. Description
  1023. Author: ericdav
  1024. ---------------------------------------------------------------------------*/
  1025. void
  1026. CActiveRegistrationsHandler::DatabaseLoadingCleanup()
  1027. {
  1028. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1029. m_winsdbState = WINSDB_NORMAL;
  1030. // check for any errors
  1031. HRESULT hrLastError;
  1032. m_spWinsDatabase->GetLastError(&hrLastError);
  1033. // Kill the timer thread
  1034. if (m_spQuery)
  1035. {
  1036. // Signal the thread to abort
  1037. m_spQuery->SetAbortEvent();
  1038. }
  1039. if (FAILED(hrLastError))
  1040. {
  1041. CString strError, strIp;
  1042. LPTSTR pBuf = strIp.GetBuffer(256);
  1043. m_spWinsDatabase->GetIP(pBuf, 256);
  1044. strIp.ReleaseBuffer();
  1045. AfxFormatString1(strError, IDS_ERR_LOADING_DB, strIp);
  1046. theApp.MessageBox(strError, WIN32_FROM_HRESULT(hrLastError));
  1047. m_fForceReload = TRUE;
  1048. }
  1049. WaitForThreadToExit();
  1050. }
  1051. void
  1052. CActiveRegistrationsHandler::FilterCleanup(ITFSNode *pNode)
  1053. {
  1054. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1055. m_winsdbState = WINSDB_NORMAL;
  1056. // check for any errors
  1057. HRESULT hrLastError;
  1058. m_spWinsDatabase->GetLastError(&hrLastError);
  1059. // Kill the timer thread
  1060. if (m_spQuery)
  1061. {
  1062. // Signal the thread to abort
  1063. m_spQuery->SetAbortEvent();
  1064. }
  1065. if (FAILED(hrLastError))
  1066. {
  1067. CString strError, strIp;
  1068. LPTSTR pBuf = strIp.GetBuffer(256);
  1069. m_spWinsDatabase->GetIP(pBuf, 256);
  1070. strIp.ReleaseBuffer();
  1071. AfxFormatString1(strError, IDS_ERR_LOADING_DB, strIp);
  1072. theApp.MessageBox(strError, WIN32_FROM_HRESULT(hrLastError));
  1073. m_fForceReload = TRUE;
  1074. }
  1075. WaitForThreadToExit();
  1076. // change the icon to normal
  1077. pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
  1078. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
  1079. pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM);
  1080. }
  1081. /*---------------------------------------------------------------------------
  1082. CActiveRegistrationsHandler::UpdateListboxCount
  1083. Description
  1084. ---------------------------------------------------------------------------*/
  1085. HRESULT
  1086. CActiveRegistrationsHandler::UpdateListboxCount(ITFSNode * pNode, BOOL bClear)
  1087. {
  1088. HRESULT hr = hrOK;
  1089. SPIComponentData spCompData;
  1090. SPIConsole spConsole;
  1091. IDataObject* pDataObject;
  1092. LONG_PTR hint;
  1093. // need to pass up two counter values:one is the total number of records scanned
  1094. // the other is the total number of records filtered. I put these two in a 64 bit
  1095. // value: the most significant 32bits is the number of records actually filtered
  1096. // the less significant 32bits is the total number of records scanned.
  1097. ULARGE_INTEGER data;
  1098. ULARGE_INTEGER *pData;
  1099. COM_PROTECT_TRY
  1100. {
  1101. if (!m_pCurrentDatabase)
  1102. {
  1103. pData = NULL;
  1104. hint = RESULT_PANE_CLEAR_VIRTUAL_LB;
  1105. }
  1106. else
  1107. {
  1108. CORg (m_pCurrentDatabase->GetCurrentScanned((int*)&data.LowPart));
  1109. CORg (m_pCurrentDatabase->GetCurrentCount((int*)&data.HighPart));
  1110. hint = RESULT_PANE_SET_VIRTUAL_LB_SIZE;
  1111. pData = &data;
  1112. }
  1113. m_spNodeMgr->GetComponentData(&spCompData);
  1114. CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode,
  1115. CCT_RESULT,
  1116. &pDataObject) );
  1117. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  1118. CORg ( spConsole->UpdateAllViews(pDataObject,
  1119. (LPARAM)pData,
  1120. hint) );
  1121. pDataObject->Release();
  1122. COM_PROTECT_ERROR_LABEL;
  1123. }
  1124. COM_PROTECT_CATCH
  1125. return hr;
  1126. }
  1127. /*---------------------------------------------------------------------------
  1128. CActiveRegistrationsHandler::UpdateVerbs
  1129. Description
  1130. ---------------------------------------------------------------------------*/
  1131. HRESULT
  1132. CActiveRegistrationsHandler::UpdateVerbs(ITFSNode * pNode)
  1133. {
  1134. HRESULT hr = hrOK;
  1135. LONG_PTR hint;
  1136. int i;
  1137. COM_PROTECT_TRY
  1138. {
  1139. g_ConsoleVerbStates[WINSSNAP_ACTIVE_REGISTRATIONS][6] = ENABLED;
  1140. if (!pNode)
  1141. {
  1142. hint = WINSSNAP_REGISTRATION;
  1143. }
  1144. else
  1145. {
  1146. hint = WINSSNAP_ACTIVE_REGISTRATIONS;
  1147. }
  1148. UpdateStandardVerbs(pNode, hint);
  1149. }
  1150. COM_PROTECT_CATCH
  1151. return hr;
  1152. }
  1153. /*---------------------------------------------------------------------------
  1154. Command handlers
  1155. ---------------------------------------------------------------------------*/
  1156. /*---------------------------------------------------------------------------
  1157. CActiveRegistrationsHandler::GetServerIP
  1158. Description
  1159. Author: v-shubk
  1160. ---------------------------------------------------------------------------*/
  1161. void
  1162. CActiveRegistrationsHandler::GetServerIP(ITFSNode * pNode,
  1163. DWORD &dwIP,
  1164. CString &strIP)
  1165. {
  1166. SPITFSNode spServerNode;
  1167. pNode->GetParent(&spServerNode);
  1168. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  1169. dwIP = pServer->GetServerIP();
  1170. ::MakeIPAddress(dwIP, strIP);
  1171. }
  1172. /*---------------------------------------------------------------------------
  1173. CActiveRegistrationsHandler::OnCreateMapping
  1174. Description
  1175. Author: v-shubk
  1176. ---------------------------------------------------------------------------*/
  1177. HRESULT
  1178. CActiveRegistrationsHandler::OnCreateMapping(ITFSNode *pNode)
  1179. {
  1180. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1181. HRESULT hr = hrOK;
  1182. // Object gets deleted when the page is destroyed
  1183. SPIComponentData spComponentData;
  1184. m_spNodeMgr->GetComponentData(&spComponentData);
  1185. // HACK WARNING: because we do this in a MMC provided property sheet, we
  1186. // need to invoke the correct mechanism so we get a callback handle.
  1187. // otherwise when we create the static mapping, we're on another thread
  1188. // and it can do bad things when we try to update the UI
  1189. hr = DoPropertiesOurselvesSinceMMCSucks(pNode, spComponentData, _T(""));
  1190. return hr;
  1191. }
  1192. /*---------------------------------------------------------------------------
  1193. CActiveRegistrationsHandler::OnDatabaseLoadStart
  1194. Description
  1195. ---------------------------------------------------------------------------*/
  1196. HRESULT
  1197. CActiveRegistrationsHandler::OnDatabaseLoadStart(ITFSNode *pNode)
  1198. {
  1199. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1200. HRESULT hr = hrOK;
  1201. SPITFSNode spNode;
  1202. SPITFSNodeHandler spHandler;
  1203. ITFSQueryObject * pQuery = NULL;
  1204. SPITFSNode spServerNode;
  1205. DWORD dwIP;
  1206. CString strIP;
  1207. BOOL fReload = FALSE;
  1208. int nCount, pos;
  1209. CTypeFilterInfo typeFilterInfo;
  1210. pNode->GetParent(&spServerNode);
  1211. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  1212. dwIP = pServer->GetServerIP();
  1213. if (!m_bExpanded)
  1214. {
  1215. m_dlgLoadRecords.ResetFiltering();
  1216. }
  1217. if (m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.GetSize() == 0)
  1218. {
  1219. fReload = TRUE;
  1220. // initialize the record type filter array
  1221. for (nCount = 0; nCount < m_NameTypeMap.GetSize(); nCount++)
  1222. {
  1223. if (m_NameTypeMap[nCount].dwWinsType == -1)
  1224. {
  1225. typeFilterInfo.dwType = m_NameTypeMap[nCount].dwNameType;
  1226. typeFilterInfo.fShow = TRUE;
  1227. m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.Add(typeFilterInfo);
  1228. }
  1229. }
  1230. }
  1231. // if a download is running, ask the user if they want to stop it
  1232. if (m_winsdbState != WINSDB_NORMAL)
  1233. {
  1234. OnDatabaseLoadStop(pNode);
  1235. }
  1236. // bring up the Owner Dialog
  1237. // fill in the owner page info
  1238. GetOwnerInfo(m_dlgLoadRecords.m_pageOwners.m_ServerInfoArray);
  1239. // fill in the type filter page info
  1240. m_dlgLoadRecords.m_pageTypes.m_pNameTypeMap = &m_NameTypeMap;
  1241. // save the original number of owners. In case this is one
  1242. // and several other are added, will reload the database.
  1243. //------------------Display popup ----------------------------
  1244. {
  1245. // for some reason, when activating the theme, the "load records" dialog
  1246. // doesn't show the state boxes images in the "owner list" and "type list".
  1247. CThemeContextActivator themeActivator;
  1248. if (m_dlgLoadRecords.DoModal() != IDOK)
  1249. return hrFalse;
  1250. }
  1251. SetLoadedOnce(pNode);
  1252. m_fDbLoaded = TRUE;
  1253. Lock();
  1254. MakeIPAddress(dwIP, strIP);
  1255. // stop the database if we were loading or create one if we haven't yet
  1256. if (!m_spWinsDatabase)
  1257. {
  1258. CORg (CreateWinsDatabase(strIP, strIP, &m_spWinsDatabase));
  1259. fReload = TRUE;
  1260. }
  1261. else
  1262. {
  1263. CORg (m_spWinsDatabase->Stop());
  1264. }
  1265. //~~~~~~~~~~~~~~~~~~~~~~~~~ need to revise the logic for reloading ~~~~~~~~~~~~~~~~~~~~~~~~~
  1266. //
  1267. // we try to make the decision whether the records we already loaded (if we did) are sufficient
  1268. // to apply the new filters: set fReload to TRUE if reload is needed or to FALSE otherwise.
  1269. // Since fReload could have been already set go into this process only if reloading is not yet
  1270. // decided. Assume reload will eventualy be decided and break out as soon as this is confirmed
  1271. // If the end of the "while" block is reached, this means database doesn't need to be reloaded
  1272. // so break out.
  1273. while(!fReload)
  1274. {
  1275. BOOL bDbCacheEnabled;
  1276. // assume a reload will be needed
  1277. fReload = TRUE;
  1278. // if reload imposed by external causes (first time call or refresh was done), break out
  1279. if (m_fForceReload)
  1280. break;
  1281. m_spWinsDatabase->GetCachingFlag(&bDbCacheEnabled);
  1282. if (bDbCacheEnabled)
  1283. {
  1284. BOOL bReload;
  1285. // currently the database is loaded with "enable caching" checked. This means:
  1286. // if db "owner" api setting is set (non 0xffffffff) then
  1287. // all records owned by "owner" are loaded (case 1)
  1288. // else --> "owner" is set to "multiple" (0xffffffff)
  1289. // if db "name" api is set (non null) then
  1290. // all records prefixed with "name" are loaded (case 2)
  1291. // else
  1292. // entire database is loaded (case 3)
  1293. // .
  1294. // .
  1295. // if (case 1) applies then
  1296. // if we want to filter on a different or no owner then
  1297. // reload SUGGESTED
  1298. // else
  1299. // reload NOT SUGGESTED
  1300. // .
  1301. // else if (case 2) applies then
  1302. // if we want to filter on a different or no name prefix then
  1303. // reload SUGGESTED
  1304. // else
  1305. // reload NOT SUGGESTED
  1306. // .
  1307. // else if (case 3) applies)
  1308. // reload NOT SUGGESTED
  1309. // .
  1310. //
  1311. // This logic is followed in CheckApiInfoCovered call from below
  1312. m_spWinsDatabase->ReloadSuggested(
  1313. m_dlgLoadRecords.m_pageOwners.GetOwnerForApi(),
  1314. m_dlgLoadRecords.m_pageIpAddress.GetNameForApi(),
  1315. &bReload);
  1316. if (bReload)
  1317. break;
  1318. }
  1319. else
  1320. {
  1321. // currently the database is loaded without "enable caching" checked. This means:
  1322. // the records currentLy in the database match all the filters as they were specified
  1323. // in the filtering dialog before it was popped-up. Consequently, if any of these
  1324. // filters (owner, name, ipaddr, type) changed, database has to be reloaded. Otherwise,
  1325. // since the filters are the same.
  1326. if (m_dlgLoadRecords.m_pageIpAddress.m_bDirtyName ||
  1327. m_dlgLoadRecords.m_pageIpAddress.m_bDirtyAddr ||
  1328. m_dlgLoadRecords.m_pageIpAddress.m_bDirtyMask ||
  1329. m_dlgLoadRecords.m_pageOwners.m_bDirtyOwners ||
  1330. m_dlgLoadRecords.m_pageTypes.m_bDirtyTypes)
  1331. break;
  1332. }
  1333. // if we are here it means reload is not actually needed, so reset the flag back and
  1334. // break the loop
  1335. fReload = FALSE;
  1336. break;
  1337. };
  1338. // if the final decision is to reload the db, then prepare this operation
  1339. if (fReload)
  1340. {
  1341. m_fForceReload = FALSE;
  1342. m_spWinsDatabase->Clear();
  1343. // set the Api parameters to be used by the database
  1344. m_spWinsDatabase->SetApiInfo(
  1345. m_dlgLoadRecords.m_pageOwners.GetOwnerForApi(),
  1346. m_dlgLoadRecords.m_pageIpAddress.GetNameForApi(),
  1347. m_dlgLoadRecords.m_bEnableCache);
  1348. }
  1349. //
  1350. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1351. UpdateCurrentView(pNode);
  1352. // start loading records if necessary
  1353. if (fReload)
  1354. {
  1355. // start loading records
  1356. CORg (m_spWinsDatabase->Init());
  1357. // update our internal state
  1358. m_winsdbState = WINSDB_LOADING;
  1359. // update the node's icon
  1360. OnChangeState(pNode);
  1361. // kick off the background thread to do the timer updates
  1362. pQuery = OnCreateQuery(pNode);
  1363. Assert(pQuery);
  1364. Verify(StartBackgroundThread(pNode,
  1365. m_spTFSCompData->GetHiddenWnd(),
  1366. pQuery));
  1367. pQuery->Release();
  1368. }
  1369. // fill in any record type filter information
  1370. nCount = (int)m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.GetSize();
  1371. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_TYPE);
  1372. for (pos = 0; pos < nCount; pos++)
  1373. {
  1374. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_TYPE,
  1375. m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].dwType,
  1376. m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].fShow,
  1377. NULL);
  1378. }
  1379. // fill in any owner filter information
  1380. nCount = (int)m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter.GetSize();
  1381. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_OWNER);
  1382. for (pos = 0; pos < nCount; pos++)
  1383. {
  1384. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_OWNER,
  1385. m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter[pos],
  1386. 0,
  1387. NULL);
  1388. }
  1389. // fill in any ip address filter information
  1390. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_IPADDR);
  1391. if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterIpAddr)
  1392. {
  1393. nCount = (int)m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs.GetSize();
  1394. for (pos = 0; pos < nCount; pos++)
  1395. {
  1396. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_IPADDR,
  1397. m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs[pos],
  1398. m_dlgLoadRecords.m_pageIpAddress.GetIPMaskForFilter(pos),
  1399. NULL);
  1400. }
  1401. }
  1402. // fill in any name filter information
  1403. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_NAME);
  1404. if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterName)
  1405. {
  1406. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_NAME,
  1407. m_dlgLoadRecords.m_pageIpAddress.m_bMatchCase,
  1408. 0,
  1409. m_dlgLoadRecords.m_pageIpAddress.m_strName);
  1410. }
  1411. // now that the filters are all set database can start downloading
  1412. if (fReload)
  1413. // start loading records
  1414. CORg (m_spWinsDatabase->Start());
  1415. BEGIN_WAIT_CURSOR
  1416. Sleep(100);
  1417. // filter any records that may have been downloaded before we set the
  1418. // filter information (in the case when we had to reload the database).
  1419. // any records that come in after we set the
  1420. // filter info will be filtered correctly.
  1421. m_spWinsDatabase->FilterRecords(WINSDB_FILTER_BY_TYPE, 0,0);
  1422. END_WAIT_CURSOR
  1423. if (fReload)
  1424. {
  1425. // do the initial update of the virutal listbox
  1426. OnHaveData(pNode, 0, QDATA_TIMER);
  1427. }
  1428. else
  1429. {
  1430. // just a filter changed, just need to update the result pane
  1431. UpdateListboxCount(pNode);
  1432. }
  1433. COM_PROTECT_ERROR_LABEL;
  1434. return hr;
  1435. }
  1436. /*---------------------------------------------------------------------------
  1437. CActiveRegistrationsHandler::OnDatabaseLoadStop
  1438. Description
  1439. ---------------------------------------------------------------------------*/
  1440. HRESULT
  1441. CActiveRegistrationsHandler::OnDatabaseLoadStop(ITFSNode *pNode)
  1442. {
  1443. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1444. HRESULT hr = hrOK;
  1445. CThemeContextActivator themeActivator;
  1446. if (IDYES != AfxMessageBox(IDS_STOP_DB_LOAD_CONFIRM, MB_YESNO))
  1447. {
  1448. return hrFalse;
  1449. }
  1450. if (m_spWinsDatabase)
  1451. {
  1452. CORg (m_spWinsDatabase->Stop());
  1453. DatabaseLoadingCleanup();
  1454. UpdateListboxCount(pNode);
  1455. }
  1456. m_fForceReload = TRUE;
  1457. COM_PROTECT_ERROR_LABEL;
  1458. return hr;
  1459. }
  1460. /*---------------------------------------------------------------------------
  1461. CActiveRegistrationsHandler::OnGetResultViewType
  1462. Description
  1463. ---------------------------------------------------------------------------*/
  1464. HRESULT
  1465. CActiveRegistrationsHandler::OnGetResultViewType
  1466. (
  1467. ITFSComponent * pComponent,
  1468. MMC_COOKIE cookie,
  1469. LPOLESTR * ppViewType,
  1470. long * pViewOptions
  1471. )
  1472. {
  1473. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1474. HRESULT hr = S_FALSE;
  1475. if (cookie != NULL)
  1476. {
  1477. // call the base class to see if it is handling this
  1478. if (CMTWinsHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions) != S_OK)
  1479. {
  1480. *pViewOptions = MMC_VIEW_OPTIONS_OWNERDATALIST |
  1481. MMC_VIEW_OPTIONS_MULTISELECT;
  1482. hr = S_FALSE;
  1483. }
  1484. }
  1485. return hr;
  1486. }
  1487. /*---------------------------------------------------------------------------
  1488. CActiveRegistrationsHandler::GetVirtualImage
  1489. Description
  1490. Author: EricDav
  1491. ---------------------------------------------------------------------------*/
  1492. int
  1493. CActiveRegistrationsHandler::GetVirtualImage
  1494. (
  1495. int nIndex
  1496. )
  1497. {
  1498. HRESULT hr = hrOK;
  1499. WinsRecord ws;
  1500. HROW hrow;
  1501. int nImage = ICON_IDX_CLIENT;
  1502. COM_PROTECT_TRY
  1503. {
  1504. if (!m_pCurrentDatabase)
  1505. return -1;
  1506. CORg (m_pCurrentDatabase->GetHRow(nIndex, &hrow));
  1507. CORg (m_pCurrentDatabase->GetData(hrow, &ws));
  1508. if (HIWORD(ws.dwType) != WINSINTF_E_UNIQUE)
  1509. {
  1510. nImage = ICON_IDX_CLIENT_GROUP;
  1511. }
  1512. COM_PROTECT_ERROR_LABEL;
  1513. }
  1514. COM_PROTECT_CATCH
  1515. return nImage;
  1516. }
  1517. /*---------------------------------------------------------------------------
  1518. CActiveRegistrationsHandler::GetVirtualString
  1519. Description
  1520. Author: EricDav
  1521. ---------------------------------------------------------------------------*/
  1522. LPCWSTR
  1523. CActiveRegistrationsHandler::GetVirtualString
  1524. (
  1525. int nIndex,
  1526. int nCol
  1527. )
  1528. {
  1529. HRESULT hr;
  1530. int nCount;
  1531. if (m_pCurrentDatabase)
  1532. {
  1533. // check if nIndex is within limits, if not crashes when the last
  1534. // record deleted and properties chosen.
  1535. m_pCurrentDatabase->GetCurrentCount(&nCount);
  1536. // 0 based index
  1537. if (nIndex < 0 || nIndex >= nCount)
  1538. {
  1539. return NULL;
  1540. }
  1541. }
  1542. // check our cache to see if we have this one.
  1543. WinsStrRecord * pwsr = m_RecList.FindItem(nIndex);
  1544. if (pwsr == NULL)
  1545. {
  1546. Trace1("ActRegHandler::GetVirtualString - Index %d not in string cache\n", nIndex);
  1547. // doesn't exist in our cache, need to add this one.
  1548. pwsr = BuildWinsStrRecord(nIndex);
  1549. if (pwsr)
  1550. m_RecList.AddTail(pwsr);
  1551. }
  1552. if (pwsr)
  1553. {
  1554. switch (nCol)
  1555. {
  1556. case ACTREG_COL_NAME:
  1557. return pwsr->strName;
  1558. break;
  1559. case ACTREG_COL_TYPE:
  1560. return pwsr->strType;
  1561. break;
  1562. case ACTREG_COL_IPADDRESS:
  1563. return pwsr->strIPAdd;
  1564. break;
  1565. case ACTREG_COL_STATE:
  1566. return pwsr->strActive;
  1567. break;
  1568. case ACTREG_COL_STATIC:
  1569. return pwsr->strStatic;
  1570. break;
  1571. case ACTREG_COL_OWNER:
  1572. return pwsr->strOwner;
  1573. break;
  1574. case ACTREG_COL_VERSION:
  1575. return pwsr->strVersion;
  1576. break;
  1577. case ACTREG_COL_EXPIRATION:
  1578. return pwsr->strExpiration;
  1579. break;
  1580. default:
  1581. Panic0("ActRegHandler::GetVirtualString - Unknown column!\n");
  1582. break;
  1583. }
  1584. }
  1585. return NULL;
  1586. }
  1587. /*---------------------------------------------------------------------------
  1588. CActiveRegistrationsHandler::BuildWinsStrRecord
  1589. Description
  1590. Author: EricDav
  1591. ---------------------------------------------------------------------------*/
  1592. WinsStrRecord *
  1593. CActiveRegistrationsHandler::BuildWinsStrRecord(int nIndex)
  1594. {
  1595. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1596. int nCount;
  1597. HRESULT hr = hrOK;
  1598. WinsStrRecord * pwsr = NULL;
  1599. WinsRecord ws;
  1600. HROW hrow;
  1601. CString strTemp;
  1602. if (!m_pCurrentDatabase)
  1603. {
  1604. return NULL;
  1605. }
  1606. if (FAILED(m_pCurrentDatabase->GetHRow(nIndex, &hrow)))
  1607. return NULL;
  1608. if (FAILED(m_pCurrentDatabase->GetData(hrow, &ws)))
  1609. return NULL;
  1610. COM_PROTECT_TRY
  1611. {
  1612. pwsr = new WinsStrRecord;
  1613. // set the index for this record
  1614. pwsr->nIndex = nIndex;
  1615. // build the name string
  1616. CleanNetBIOSName(ws.szRecordName,
  1617. pwsr->strName,
  1618. TRUE, // Expand
  1619. TRUE, // Truncate
  1620. IsLanManCompatible(),
  1621. TRUE, // name is OEM
  1622. FALSE, // No double backslash
  1623. ws.dwNameLen);
  1624. // now the type
  1625. CString strValue;
  1626. strValue.Format(_T("[%02Xh] "),
  1627. ((int) ws.szRecordName[15] & 0x000000FF));
  1628. CString strName;
  1629. DWORD dwNameType = (0x000000FF & ws.szRecordName[15]);
  1630. m_NameTypeMap.TypeToCString(dwNameType, MAKELONG(HIWORD(ws.dwType), 0), strName);
  1631. pwsr->strType = strValue + strName;
  1632. // IP address
  1633. // Gets changed in the case of static records of the type Special Group,
  1634. // where the first IP address in the list of IP addresses is of the Owner
  1635. if ( (ws.dwState & WINSDB_REC_UNIQUE) ||
  1636. (ws.dwState & WINSDB_REC_NORM_GROUP) )
  1637. {
  1638. MakeIPAddress(ws.dwIpAdd[0], pwsr->strIPAdd);
  1639. }
  1640. else
  1641. {
  1642. if (ws.dwNoOfAddrs > 0)
  1643. {
  1644. if (ws.dwIpAdd[1] == 0)
  1645. {
  1646. pwsr->strIPAdd.Empty();
  1647. }
  1648. else
  1649. {
  1650. MakeIPAddress(ws.dwIpAdd[1], pwsr->strIPAdd);
  1651. }
  1652. }
  1653. else
  1654. {
  1655. pwsr->strIPAdd.Empty();
  1656. }
  1657. }
  1658. // active status
  1659. GetStateString(ws.dwState, pwsr->strActive);
  1660. // static flag
  1661. if (ws.dwState & WINSDB_REC_STATIC)
  1662. {
  1663. pwsr->strStatic = _T("x");
  1664. }
  1665. else
  1666. {
  1667. pwsr->strStatic = _T("");
  1668. }
  1669. // expiration time
  1670. if (ws.dwExpiration == INFINITE_EXPIRATION)
  1671. {
  1672. Verify(pwsr->strExpiration.LoadString(IDS_INFINITE));
  1673. }
  1674. else
  1675. {
  1676. CTime time(ws.dwExpiration);
  1677. FormatDateTime(pwsr->strExpiration, time);
  1678. }
  1679. // version
  1680. GetVersionInfo(ws.liVersion.LowPart,
  1681. ws.liVersion.HighPart,
  1682. pwsr->strVersion);
  1683. // owner
  1684. if (m_Config.FSupportsOwnerId())
  1685. {
  1686. MakeIPAddress(ws.dwOwner, pwsr->strOwner);
  1687. }
  1688. }
  1689. COM_PROTECT_CATCH
  1690. return pwsr;
  1691. }
  1692. /*---------------------------------------------------------------------------
  1693. CActiveRegistrationsHandler::GetStateString
  1694. Description Returns the state of the record, Active, Tomstoned,
  1695. realeased or deleted
  1696. Author: v-shubk
  1697. ---------------------------------------------------------------------------*/
  1698. void CActiveRegistrationsHandler::GetStateString(DWORD dwState,
  1699. CString& strState)
  1700. {
  1701. if (dwState & WINSDB_REC_ACTIVE )
  1702. {
  1703. strState.LoadString(IDS_RECORD_STATE_ACTIVE);
  1704. }
  1705. else
  1706. if (dwState & WINSDB_REC_DELETED )
  1707. {
  1708. strState.LoadString(IDS_RECORD_STATE_DELETED);
  1709. }
  1710. else
  1711. if (dwState & WINSDB_REC_RELEASED )
  1712. {
  1713. strState.LoadString(IDS_RECORD_STATE_RELEASED);
  1714. }
  1715. else
  1716. if (dwState & WINSDB_REC_TOMBSTONE )
  1717. {
  1718. strState.LoadString(IDS_RECORD_STATE_TOMBSTONED);
  1719. }
  1720. else
  1721. {
  1722. strState.LoadString(IDS_RECORD_STATE_UNKNOWN);
  1723. }
  1724. }
  1725. /*---------------------------------------------------------------------------
  1726. CActiveRegistrationsHandler::GetStateString
  1727. Description Returns the static type for the record, Unique,
  1728. Multihomed, Inetrne Group, Normal Group, Multihomed
  1729. Author: v-shubk
  1730. ---------------------------------------------------------------------------*/
  1731. void CActiveRegistrationsHandler::GetStaticTypeString(DWORD dwState,
  1732. CString& strStaticType)
  1733. {
  1734. if (dwState & WINSDB_REC_UNIQUE )
  1735. {
  1736. strStaticType = g_strStaticTypeUnique;
  1737. }
  1738. else
  1739. if (dwState & WINSDB_REC_SPEC_GROUP )
  1740. {
  1741. strStaticType = g_strStaticTypeDomainName;
  1742. }
  1743. else
  1744. if (dwState & WINSDB_REC_MULTIHOMED )
  1745. {
  1746. strStaticType = g_strStaticTypeMultihomed;
  1747. }
  1748. else
  1749. if (dwState & WINSDB_REC_NORM_GROUP )
  1750. {
  1751. strStaticType = g_strStaticTypeGroup;
  1752. }
  1753. else
  1754. {
  1755. strStaticType = g_strStaticTypeUnknown;
  1756. }
  1757. }
  1758. /*---------------------------------------------------------------------------
  1759. CActiveRegistrationsHandler::GetVersionInfo
  1760. Description Gives the version INfo as string in Hex Notation
  1761. Author: v-shubk
  1762. ---------------------------------------------------------------------------*/
  1763. void CActiveRegistrationsHandler::GetVersionInfo(LONG lLowWord,
  1764. LONG lHighWord,
  1765. CString& strVersionCount)
  1766. {
  1767. strVersionCount.Empty();
  1768. TCHAR sz[20];
  1769. TCHAR *pch = sz;
  1770. ::wsprintf(sz, _T("%08lX%08lX"), lHighWord, lLowWord);
  1771. // Kill leading zero's
  1772. while (*pch == '0')
  1773. {
  1774. ++pch;
  1775. }
  1776. // At least one digit...
  1777. if (*pch == '\0')
  1778. {
  1779. --pch;
  1780. }
  1781. strVersionCount = pch;
  1782. }
  1783. BOOL
  1784. CActiveRegistrationsHandler::IsLanManCompatible()
  1785. {
  1786. BOOL fCompatible = TRUE;
  1787. if (m_spServerNode)
  1788. {
  1789. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, m_spServerNode);
  1790. fCompatible = (pServer->m_dwFlags & FLAG_LANMAN_COMPATIBLE) ? TRUE : FALSE;
  1791. }
  1792. return fCompatible;
  1793. }
  1794. //
  1795. // Convert the netbios name to a displayable format, with
  1796. // beginning slashes, the unprintable characters converted
  1797. // to '-' characters, and the 16th character displayed in brackets.
  1798. // Convert the string to ANSI/Unicode before displaying it.
  1799. //
  1800. //
  1801. void
  1802. CActiveRegistrationsHandler::CleanNetBIOSName
  1803. (
  1804. LPCSTR lpszSrc,
  1805. CString & strDest,
  1806. BOOL fExpandChars,
  1807. BOOL fTruncate,
  1808. BOOL fLanmanCompatible,
  1809. BOOL fOemName,
  1810. BOOL fWackwack,
  1811. int nLength
  1812. )
  1813. {
  1814. static CHAR szWacks[] = "\\\\";
  1815. BYTE ch16 = 0;
  1816. if (!lpszSrc ||
  1817. (strcmp(lpszSrc, "") == 0) )
  1818. {
  1819. strDest = _T("---------");
  1820. return;
  1821. }
  1822. int nLen, nDisplayLen;
  1823. int nMaxDisplayLen = fLanmanCompatible ? 15 : 16;
  1824. if (!fWackwack && fLanmanCompatible)
  1825. {
  1826. //
  1827. // Don't want backslahes, but if they do exist,
  1828. // remove them.
  1829. //
  1830. if (!::strncmp(lpszSrc, szWacks, ::strlen(szWacks)))
  1831. {
  1832. lpszSrc += ::strlen(szWacks);
  1833. if (nLength)
  1834. {
  1835. nLength -= 2;
  1836. }
  1837. }
  1838. }
  1839. if ((nDisplayLen = nLen = nLength ? nLength : ::strlen(lpszSrc)) > 15)
  1840. {
  1841. ch16 = (BYTE)lpszSrc[15];
  1842. nDisplayLen = fTruncate ? nMaxDisplayLen : nLen;
  1843. }
  1844. char szTarget[MAX_PATH] = {0};
  1845. char szRestore[MAX_PATH] = {0};
  1846. char * pTarget = &szTarget[0];
  1847. if (fWackwack)
  1848. {
  1849. ::strcpy(pTarget, szWacks);
  1850. pTarget += ::strlen(szWacks);
  1851. }
  1852. if (lpszSrc == NULL)
  1853. {
  1854. int i = 1;
  1855. }
  1856. if (fOemName)
  1857. {
  1858. ::OemToCharBuffA(lpszSrc, pTarget, nLen);
  1859. }
  1860. else
  1861. {
  1862. ::memcpy(pTarget, lpszSrc, nLen);
  1863. }
  1864. int n = 0;
  1865. while (n < nDisplayLen)
  1866. {
  1867. if (fExpandChars)
  1868. {
  1869. #ifdef FE_SB
  1870. if (::IsDBCSLeadByte(*pTarget))
  1871. {
  1872. ++n;
  1873. ++pTarget;
  1874. }
  1875. else if (!WinsIsPrint(pTarget))
  1876. #else
  1877. if (!WinsIsPrint(pTarget))
  1878. #endif // FE_SB
  1879. {
  1880. *pTarget = BADNAME_CHAR;
  1881. }
  1882. }
  1883. ++n;
  1884. ++pTarget;
  1885. }
  1886. if (fLanmanCompatible)
  1887. {
  1888. //
  1889. // Back up over the spaces.
  1890. //
  1891. while (*(--pTarget) == ' ') /**/ ;
  1892. ++pTarget;
  1893. }
  1894. // if there's a scope name attached, append the scope name
  1895. // to the strTarget before returning.
  1896. // check the length of lpSrc, if greater than NetBIOS name
  1897. // length, it has a scope name attached
  1898. if (nLength > 16)
  1899. {
  1900. if (lpszSrc[0x10] == '.')
  1901. {
  1902. ::OemToCharBuffA(&lpszSrc[0x10], szRestore, sizeof(szRestore));
  1903. memcpy(pTarget, szRestore, nLength - 16);
  1904. pTarget += (nLength - 16);
  1905. }
  1906. }
  1907. *pTarget = '\0';
  1908. // convert the string to unicode. We've already done the oem to ansi
  1909. // conversion so use the Ansi code page now
  1910. MBCSToWide(szTarget, strDest, CP_ACP);
  1911. }
  1912. /*---------------------------------------------------------------------------
  1913. CActiveRegistrationsHandler::CacheHint
  1914. Description
  1915. Author: EricDav
  1916. ---------------------------------------------------------------------------*/
  1917. STDMETHODIMP
  1918. CActiveRegistrationsHandler::CacheHint
  1919. (
  1920. int nStartIndex,
  1921. int nEndIndex
  1922. )
  1923. {
  1924. HRESULT hr = hrOK;
  1925. HROW hrow;
  1926. Trace2("CacheHint - Start %d, End %d\n", nStartIndex, nEndIndex);
  1927. m_RecList.RemoveAllEntries();
  1928. WinsRecord ws;
  1929. WinsStrRecord * pwsr;
  1930. for (int i = nStartIndex; i <= nEndIndex; i++)
  1931. {
  1932. pwsr = BuildWinsStrRecord(i);
  1933. if (pwsr)
  1934. m_RecList.AddTail(pwsr);
  1935. }
  1936. return hr;
  1937. }
  1938. /*---------------------------------------------------------------------------
  1939. CActiveRegistrationsHandler::SortItems
  1940. Description
  1941. Author: EricDav, v-shubk
  1942. ---------------------------------------------------------------------------*/
  1943. STDMETHODIMP
  1944. CActiveRegistrationsHandler::SortItems
  1945. (
  1946. int nColumn,
  1947. DWORD dwSortOptions,
  1948. LPARAM lUserParam
  1949. )
  1950. {
  1951. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1952. CThemeContextActivator themeActivator;
  1953. HRESULT hr = hrOK;
  1954. WINSDB_STATE uState = WINSDB_NORMAL;
  1955. if (!m_pCurrentDatabase)
  1956. {
  1957. return hr;
  1958. }
  1959. m_pCurrentDatabase->GetCurrentState(&uState);
  1960. if (uState != WINSDB_NORMAL)
  1961. {
  1962. AfxMessageBox(IDS_RECORDS_DOWNLOADING, MB_OK|MB_ICONINFORMATION);
  1963. return hr;
  1964. }
  1965. // put up the busy dialog
  1966. CSortWorker * pWorker = new CSortWorker(m_pCurrentDatabase,
  1967. nColumn,
  1968. dwSortOptions);
  1969. CLongOperationDialog dlgBusy(pWorker, IDR_AVI2);
  1970. dlgBusy.LoadTitleString(IDS_SNAPIN_DESC);
  1971. dlgBusy.LoadDescriptionString(IDS_SORTING);
  1972. // disable the system menu and the cancel buttons
  1973. dlgBusy.EnableCancel(FALSE);
  1974. dlgBusy.DoModal();
  1975. return hr;
  1976. }
  1977. /*!--------------------------------------------------------------------------
  1978. CActiveRegistrationsHandler::SetVirtualLbSize
  1979. Sets the virtual listbox count. Over-ride this if you need to
  1980. specify and options.
  1981. Author: EricDav
  1982. ---------------------------------------------------------------------------*/
  1983. HRESULT
  1984. CActiveRegistrationsHandler::SetVirtualLbSize
  1985. (
  1986. ITFSComponent * pComponent,
  1987. LPARAM data
  1988. )
  1989. {
  1990. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1991. HRESULT hr = hrOK;
  1992. SPIResultData spResultData;
  1993. CString strDescBarText;
  1994. CString strData;
  1995. ULARGE_INTEGER nullData;
  1996. ULARGE_INTEGER *pData = (ULARGE_INTEGER *)data;
  1997. nullData.HighPart = nullData.LowPart = 0;
  1998. pData = (data == NULL)? &nullData : (ULARGE_INTEGER*)data;
  1999. // just to avoid those cases when filtered shows up larger than scanned
  2000. if (pData->LowPart < pData->HighPart)
  2001. pData->HighPart = pData->LowPart;
  2002. strDescBarText.Empty();
  2003. strDescBarText.LoadString(IDS_RECORDS_FILTERED);
  2004. strData.Format(_T(" %d -- "), pData->HighPart);
  2005. strDescBarText += strData;
  2006. strData.LoadString(IDS_RECORDS_SCANNED);
  2007. strDescBarText += strData;
  2008. strData.Format(_T(" %d"), pData->LowPart);
  2009. strDescBarText += strData;
  2010. CORg (pComponent->GetResultData(&spResultData));
  2011. if (pData->HighPart == 0)
  2012. {
  2013. //CORg (spResultData->DeleteAllRsltItems());
  2014. CORg (spResultData->SetItemCount((int) pData->HighPart, MMCLV_UPDATE_NOSCROLL));
  2015. }
  2016. else
  2017. {
  2018. CORg (spResultData->SetItemCount((int) pData->HighPart, MMCLV_UPDATE_NOSCROLL));
  2019. }
  2020. CORg (spResultData->SetDescBarText((LPTSTR) (LPCTSTR) strDescBarText));
  2021. Error:
  2022. return hr;
  2023. }
  2024. /*!--------------------------------------------------------------------------
  2025. CActiveRegistrationsHandler::UpdateCurrentView
  2026. Updates the current view -- the MenuButton control and the result
  2027. pane.
  2028. Author: EricDav
  2029. ---------------------------------------------------------------------------*/
  2030. HRESULT
  2031. CActiveRegistrationsHandler::UpdateCurrentView
  2032. (
  2033. ITFSNode * pNode
  2034. )
  2035. {
  2036. HRESULT hr = hrOK;
  2037. SPIComponentData spCompData;
  2038. SPIConsole spConsole;
  2039. IDataObject* pDataObject;
  2040. // update our current database to point to the correct one
  2041. m_pCurrentDatabase = m_spWinsDatabase;
  2042. // update our current database to point to the correct one
  2043. m_spWinsDatabase->SetActiveView(WINSDB_VIEW_FILTERED_DATABASE);
  2044. // Need to tell all of the views up update themselves with the new state.
  2045. m_spNodeMgr->GetComponentData(&spCompData);
  2046. CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode,
  2047. CCT_RESULT,
  2048. &pDataObject) );
  2049. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  2050. pDataObject->Release();
  2051. // update the listbox with the correct count for this view
  2052. UpdateListboxCount(pNode);
  2053. UpdateVerbs(pNode);
  2054. Error:
  2055. return hr;
  2056. }
  2057. /*!--------------------------------------------------------------------------
  2058. CActiveRegistrationsHandler::CompareRecName
  2059. Checks if the name matches the Find record criterion
  2060. Author: EricDav, v-shubk
  2061. ---------------------------------------------------------------------------*/
  2062. BOOL
  2063. CActiveRegistrationsHandler::CompareRecName(LPSTR szNewName)
  2064. {
  2065. // convert the MBCS name to a wide string using the OEM
  2066. // code page so we can do the compare.
  2067. CString strTemp;
  2068. MBCSToWide(szNewName, strTemp, WINS_NAME_CODE_PAGE);
  2069. // when some invalid records get passed
  2070. if (strTemp.IsEmpty())
  2071. {
  2072. return FALSE;
  2073. }
  2074. CString strFindNameU = m_strFindName;
  2075. if (!m_fMatchCase)
  2076. {
  2077. strTemp.MakeUpper();
  2078. }
  2079. int nLen = strFindNameU.GetLength();
  2080. for (int nPos = 0; nPos < nLen; nPos++)
  2081. {
  2082. if (strFindNameU[nPos] == _T('*'))
  2083. {
  2084. break;
  2085. }
  2086. // the passed record has a smaller string length
  2087. if (nPos >= strTemp.GetLength())
  2088. {
  2089. return FALSE;
  2090. }
  2091. if (strTemp[nPos] != strFindNameU[nPos])
  2092. {
  2093. return FALSE;
  2094. }
  2095. }
  2096. return TRUE;
  2097. }
  2098. /*!--------------------------------------------------------------------------
  2099. CActiveRegistrationsHandler::DeleteRegistration
  2100. Removes a registration from the server and the virtual listbox.
  2101. Need to remove the entry from both the find database and the
  2102. full database.
  2103. Author: v-shubk
  2104. ---------------------------------------------------------------------------*/
  2105. HRESULT
  2106. CActiveRegistrationsHandler::DeleteRegistration
  2107. (
  2108. ITFSComponent * pComponent,
  2109. int nIndex
  2110. )
  2111. {
  2112. HRESULT hr = hrOK;
  2113. DWORD err = 0;
  2114. CVirtualIndexArray arraySelectedIndicies;
  2115. int i;
  2116. int nCurrentCount;
  2117. WinsRecord ws;
  2118. int nCount;
  2119. SPIConsole spConsole;
  2120. LPDATAOBJECT pDataObject= NULL;
  2121. BOOL fDelete;
  2122. // ask whether to delete or tombstone the record
  2123. CDeleteRecordDlg dlgDel;
  2124. CThemeContextActivator themeActivator;
  2125. SPIResultData spResultData;
  2126. SPITFSNode spNode;
  2127. CORg (pComponent->GetResultData(&spResultData));
  2128. // build a list of the selected indicies in the virtual listbox
  2129. CORg (BuildVirtualSelectedItemList(pComponent, &arraySelectedIndicies));
  2130. nCount = (int)arraySelectedIndicies.GetSize();
  2131. dlgDel.m_fMultiple = (nCount > 1) ? TRUE : FALSE;
  2132. if (IDOK != dlgDel.DoModal())
  2133. {
  2134. return hrOK;
  2135. }
  2136. fDelete = (dlgDel.m_nDeleteRecord == 0);
  2137. BEGIN_WAIT_CURSOR
  2138. for (i = 0; i < nCount; i++)
  2139. {
  2140. HROW hrowDel;
  2141. // remove each selected index
  2142. int nDelIndex = arraySelectedIndicies.GetAt(nCount -1 - i);
  2143. // from internal storage
  2144. CORg(m_spWinsDatabase->GetHRow(nDelIndex, &hrowDel));
  2145. CORg(m_spWinsDatabase->GetData(hrowDel, &ws));
  2146. if (fDelete)
  2147. {
  2148. // delete this record
  2149. err = DeleteMappingFromServer(pComponent, &ws, nDelIndex);
  2150. }
  2151. else
  2152. {
  2153. // tombstone the record
  2154. err = TombstoneRecords(pComponent, &ws);
  2155. }
  2156. // if a particular record could not be deleted, see if they want to cancel
  2157. if (err != ERROR_SUCCESS)
  2158. {
  2159. // put up
  2160. if (WinsMessageBox(err, MB_OKCANCEL) == IDCANCEL)
  2161. {
  2162. break;
  2163. }
  2164. }
  2165. else
  2166. {
  2167. // remove from local storage if we are deleting this record
  2168. if (fDelete)
  2169. {
  2170. CORg(m_spWinsDatabase->DeleteRecord(hrowDel));
  2171. }
  2172. // remove from UI if delete is selected, othewise update the state (tombstone)
  2173. if (dlgDel.m_nDeleteRecord == 0)
  2174. {
  2175. CORg(spResultData->DeleteItem(nDelIndex, 0));
  2176. }
  2177. else
  2178. {
  2179. UpdateRecord(pComponent, &ws, nDelIndex);
  2180. }
  2181. }
  2182. }
  2183. END_WAIT_CURSOR
  2184. // get the actreg node and redraw the list box
  2185. pComponent->GetSelectedNode(&spNode);
  2186. // now set the count.. this effectively redraws the contents
  2187. CORg (m_pCurrentDatabase->GetCurrentCount(&nCurrentCount));
  2188. UpdateListboxCount(spNode);
  2189. // if we are tombstoning, then there will still be selections
  2190. // in the result pane. In this case we need to pass in NULL
  2191. // for the node type so that the verbs get updated correctly.
  2192. if (!fDelete)
  2193. spNode.Set(NULL);
  2194. // update the cuurent view
  2195. UpdateCurrentView(spNode);
  2196. Error:
  2197. return hr;
  2198. }
  2199. /*---------------------------------------------------------------------------
  2200. CActiveRegistrationsHandler:: AddMapping(ITFSNode* pNode)
  2201. Adds a new Mapping to the server
  2202. Author: v-shubk
  2203. ---------------------------------------------------------------------------*/
  2204. HRESULT
  2205. CActiveRegistrationsHandler::AddMapping(ITFSNode* pNode)
  2206. {
  2207. HRESULT hr = hrOK;
  2208. DWORD err = ERROR_SUCCESS;
  2209. // get the server
  2210. SPITFSNode spServerNode;
  2211. pNode->GetParent(&spServerNode);
  2212. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  2213. BOOL fInternetGroup = FALSE;
  2214. if (m_strStaticMappingType.CompareNoCase(g_strStaticTypeInternetGroup) == 0)
  2215. {
  2216. fInternetGroup = TRUE;
  2217. }
  2218. CString strName(m_strStaticMappingName);
  2219. // check if valid NetBIOSNAme
  2220. if (pServer->IsValidNetBIOSName(strName, IsLanManCompatible(), FALSE))
  2221. {
  2222. m_Multiples.SetNetBIOSName(m_strStaticMappingName);
  2223. m_Multiples.SetNetBIOSNameLength(m_strStaticMappingName.GetLength());
  2224. int nMappings = 0;
  2225. int i;
  2226. switch(m_nStaticMappingType)
  2227. {
  2228. case WINSINTF_E_UNIQUE:
  2229. case WINSINTF_E_NORM_GROUP:
  2230. {
  2231. nMappings = 1;
  2232. LONG l;
  2233. m_Multiples.SetIpAddress(m_lArrayIPAddress.GetAt(0));
  2234. }
  2235. break;
  2236. case WINSINTF_E_SPEC_GROUP:
  2237. case WINSINTF_E_MULTIHOMED:
  2238. nMappings = (int)m_lArrayIPAddress.GetSize();
  2239. ASSERT(nMappings <= WINSINTF_MAX_MEM);
  2240. if (!fInternetGroup && nMappings == 0)
  2241. {
  2242. //return E_FAIL;
  2243. }
  2244. for (i = 0; i < nMappings; ++i)
  2245. {
  2246. m_Multiples.SetIpAddress(i,m_lArrayIPAddress.GetAt(i) );
  2247. }
  2248. break;
  2249. default:
  2250. ASSERT(0 && "Invalid mapping type!");
  2251. }
  2252. BEGIN_WAIT_CURSOR
  2253. // add to the server
  2254. err = AddMappingToServer(pNode,
  2255. m_nStaticMappingType,
  2256. nMappings,
  2257. m_Multiples);
  2258. END_WAIT_CURSOR
  2259. if (err == ERROR_SUCCESS)
  2260. {
  2261. //
  2262. // Added succesfully
  2263. //
  2264. }
  2265. else
  2266. {
  2267. //
  2268. // WINS disallowed the mapping. Put up the
  2269. // error message, and highlight the name
  2270. //
  2271. return HRESULT_FROM_WIN32(err);
  2272. }
  2273. }
  2274. return hr;
  2275. }
  2276. /*---------------------------------------------------------------------------
  2277. CActiveRegistrationsHandler::EditMappingToServer(
  2278. ITFSNode* pNode,
  2279. int nType,
  2280. int nCount,
  2281. CMultipleIpNamePair& mipnp,
  2282. BOOL fEdit,
  2283. WinsRecord *pRecord
  2284. )
  2285. Edits the maping stored in the server database, WinsRecordAction is called
  2286. Author: v-shubk
  2287. ---------------------------------------------------------------------------*/
  2288. HRESULT
  2289. CActiveRegistrationsHandler::EditMappingToServer(
  2290. ITFSNode* pNode,
  2291. int nType,
  2292. int nCount,
  2293. CMultipleIpNamePair& mipnp,
  2294. BOOL fEdit, // Editing existing mapping?
  2295. WinsRecord *pRecord
  2296. )
  2297. {
  2298. SPITFSNode spNode;
  2299. pNode->GetParent(&spNode);
  2300. CWinsServerHandler* pServer = GETHANDLER(CWinsServerHandler, spNode);
  2301. HRESULT hr = hrOK;
  2302. WINSINTF_RECORD_ACTION_T RecAction;
  2303. PWINSINTF_RECORD_ACTION_T pRecAction;
  2304. DWORD dwLastStatus;
  2305. ASSERT(nType >= WINSINTF_E_UNIQUE && nType <= WINSINTF_E_MULTIHOMED);
  2306. ZeroMemory(&RecAction, sizeof(RecAction));
  2307. RecAction.TypOfRec_e = nType;
  2308. RecAction.Cmd_e = WINSINTF_E_INSERT;
  2309. RecAction.pAdd = NULL;
  2310. RecAction.pName = NULL;
  2311. pRecAction = &RecAction;
  2312. if (nType == WINSINTF_E_UNIQUE ||
  2313. nType == WINSINTF_E_NORM_GROUP)
  2314. {
  2315. RecAction.NoOfAdds = 1;
  2316. RecAction.Add.IPAdd = (LONG)mipnp.GetIpAddress();
  2317. RecAction.Add.Type = 0;
  2318. RecAction.Add.Len = 4;
  2319. }
  2320. else
  2321. {
  2322. ASSERT(nCount <= WINSINTF_MAX_MEM);
  2323. RecAction.pAdd = (WINSINTF_ADD_T *)::WinsAllocMem(
  2324. sizeof(WINSINTF_ADD_T) * nCount);
  2325. if (RecAction.pAdd == NULL)
  2326. {
  2327. return ERROR_NOT_ENOUGH_MEMORY;
  2328. }
  2329. RecAction.NoOfAdds = nCount;
  2330. int i;
  2331. for (i = 0; i < nCount; ++i)
  2332. {
  2333. (RecAction.pAdd+i)->IPAdd = (LONG)mipnp.GetIpAddress(i);
  2334. (RecAction.pAdd+i)->Type = 0;
  2335. (RecAction.pAdd+i)->Len = 4;
  2336. }
  2337. RecAction.NodeTyp = WINSINTF_E_PNODE;
  2338. }
  2339. RecAction.fStatic = TRUE;
  2340. // Don't copy the beginning slashes when adding.
  2341. //
  2342. int nLen = pRecord->dwNameLen;
  2343. //
  2344. // Must have at least enough room for 16 character string
  2345. //
  2346. RecAction.pName = (LPBYTE)::WinsAllocMem(nLen + 1);
  2347. if (RecAction.pName == NULL)
  2348. {
  2349. if (RecAction.pAdd)
  2350. {
  2351. ::WinsFreeMem(RecAction.pAdd);
  2352. }
  2353. return ERROR_NOT_ENOUGH_MEMORY;
  2354. }
  2355. if (fEdit)
  2356. {
  2357. //
  2358. // No need to convert if already existing in the database.
  2359. //
  2360. // convert to ASCII string and copy
  2361. ::memcpy((char *)RecAction.pName,
  2362. (LPCSTR) pRecord->szRecordName,
  2363. nLen+1
  2364. );
  2365. RecAction.NameLen = nLen;
  2366. }
  2367. else
  2368. {
  2369. ::CharToOemBuff(mipnp.GetNetBIOSName(),
  2370. (char *)RecAction.pName,
  2371. nLen
  2372. );
  2373. }
  2374. #ifdef WINS_CLIENT_APIS
  2375. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(), &pRecAction);
  2376. #else
  2377. dwLastStatus = ::WinsRecordAction(&pRecAction);
  2378. #endif WINS_CLIENT_APIS
  2379. if (RecAction.pName != NULL)
  2380. {
  2381. ::WinsFreeMem(RecAction.pName);
  2382. }
  2383. if (RecAction.pAdd != NULL)
  2384. {
  2385. ::WinsFreeMem(RecAction.pAdd);
  2386. }
  2387. return dwLastStatus;
  2388. }
  2389. /*---------------------------------------------------------------------------
  2390. CActiveRegistrationsHandler::AddMappingToServer(
  2391. ITFSNode* pNode,
  2392. int nType,
  2393. int nCount,
  2394. CMultipleIpNamePair& mipnp,
  2395. BOOL fEdit
  2396. )
  2397. Adds the cleaned record to the server, WinsRecordAction acalled with
  2398. WINSINTF_INSERT option
  2399. Author: v-shubk
  2400. ---------------------------------------------------------------------------*/
  2401. DWORD
  2402. CActiveRegistrationsHandler::AddMappingToServer(
  2403. ITFSNode* pNode,
  2404. int nType,
  2405. int nCount,
  2406. CMultipleIpNamePair& mipnp,
  2407. BOOL fEdit
  2408. )
  2409. {
  2410. HRESULT hr = hrOK;
  2411. WINSINTF_RECORD_ACTION_T RecAction;
  2412. PWINSINTF_RECORD_ACTION_T pRecAction;
  2413. SPITFSNode spNode;
  2414. pNode->GetParent(&spNode);
  2415. CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spNode);
  2416. DWORD dwLastStatus;
  2417. ASSERT(nType >= WINSINTF_E_UNIQUE && nType <= WINSINTF_E_MULTIHOMED);
  2418. ZeroMemory(&RecAction, sizeof(RecAction));
  2419. RecAction.TypOfRec_e = nType;
  2420. RecAction.Cmd_e = WINSINTF_E_INSERT;
  2421. RecAction.pAdd = NULL;
  2422. RecAction.pName = NULL;
  2423. pRecAction = &RecAction;
  2424. if (nType == WINSINTF_E_UNIQUE ||
  2425. nType == WINSINTF_E_NORM_GROUP)
  2426. {
  2427. RecAction.NoOfAdds = 1;
  2428. RecAction.Add.IPAdd = (LONG)mipnp.GetIpAddress();
  2429. RecAction.Add.Type = 0;
  2430. RecAction.Add.Len = 4;
  2431. }
  2432. else
  2433. {
  2434. ASSERT(nCount <= WINSINTF_MAX_MEM);
  2435. RecAction.pAdd = (WINSINTF_ADD_T *)::WinsAllocMem(
  2436. sizeof(WINSINTF_ADD_T) * nCount);
  2437. if (RecAction.pAdd == NULL)
  2438. {
  2439. return ERROR_NOT_ENOUGH_MEMORY;
  2440. }
  2441. RecAction.NoOfAdds = nCount;
  2442. int i;
  2443. for (i = 0; i < nCount; ++i)
  2444. {
  2445. (RecAction.pAdd+i)->IPAdd = (LONG)mipnp.GetIpAddress(i);
  2446. (RecAction.pAdd+i)->Type = 0;
  2447. (RecAction.pAdd+i)->Len = 4;
  2448. }
  2449. RecAction.NodeTyp = WINSINTF_E_PNODE;
  2450. }
  2451. RecAction.fStatic = TRUE;
  2452. //
  2453. // Don't copy the beginning slashes when adding.
  2454. //
  2455. int nLen = mipnp.GetNetBIOSNameLength();
  2456. //
  2457. // Must have at least enough room for 256 character string,
  2458. // includes the scope name too
  2459. //
  2460. RecAction.pName = (LPBYTE)::WinsAllocMem(257);
  2461. if (RecAction.pName == NULL)
  2462. {
  2463. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  2464. }
  2465. ZeroMemory(RecAction.pName, 257);
  2466. LPSTR szTemp = (char *) alloca(100);
  2467. CString strTemp = mipnp.GetNetBIOSName();
  2468. // This should be OEM
  2469. WideToMBCS(strTemp, szTemp, WINS_NAME_CODE_PAGE);
  2470. nLen = strlen(szTemp);
  2471. ::memcpy((char *)RecAction.pName,
  2472. (LPCSTR) szTemp,
  2473. nLen+1
  2474. );
  2475. if (nLen < 16)
  2476. {
  2477. if (nType == WINSINTF_E_SPEC_GROUP)
  2478. {
  2479. ::memset(RecAction.pName+nLen, (int)' ',16-nLen);
  2480. RecAction.pName[15] = 0x1C;
  2481. RecAction.pName[16] = '\0';
  2482. RecAction.NameLen = nLen = 16;
  2483. char szAppend[MAX_PATH];
  2484. if (!m_strStaticMappingScope.IsEmpty())
  2485. {
  2486. AppendScopeName((LPSTR)RecAction.pName, (LPSTR)szAppend);
  2487. strcpy((LPSTR)RecAction.pName, (LPSTR)szAppend);
  2488. RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
  2489. }
  2490. pRecAction = &RecAction;
  2491. #ifdef WINS_CLIENT_APIS
  2492. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),
  2493. &pRecAction);
  2494. #else
  2495. dwLastStatus = ::WinsRecordAction(&pRecAction);
  2496. #endif WINS_CLIENT_APIS
  2497. if (dwLastStatus != ERROR_SUCCESS)
  2498. {
  2499. }
  2500. else
  2501. {
  2502. HRESULT hr = hrOK;
  2503. // query the server for correct info
  2504. PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
  2505. if (pRecAction1 == NULL)
  2506. {
  2507. //add it to the m_spWinsDatabase
  2508. hr = AddToLocalStorage(pRecAction, pNode);
  2509. }
  2510. else
  2511. {
  2512. // the record found and correct info displayed
  2513. //add it to the m_spWinsDatabase
  2514. hr = AddToLocalStorage(pRecAction1, pNode);
  2515. free(pRecAction1->pName);
  2516. }
  2517. }
  2518. }
  2519. else
  2520. if (nType == WINSINTF_E_NORM_GROUP)
  2521. {
  2522. ::memset(RecAction.pName+nLen, (int)' ',16-nLen);
  2523. RecAction.pName[15] = 0x1E;
  2524. RecAction.pName[16] = '\0';
  2525. RecAction.NameLen = nLen = 16;
  2526. char szAppend[MAX_PATH];
  2527. if (!m_strStaticMappingScope.IsEmpty())
  2528. {
  2529. AppendScopeName((LPSTR)RecAction.pName, (LPSTR)szAppend);
  2530. strcpy((LPSTR)RecAction.pName, (LPSTR)szAppend);
  2531. RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
  2532. }
  2533. pRecAction = &RecAction;
  2534. #ifdef WINS_CLIENT_APIS
  2535. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
  2536. #else
  2537. dwLastStatus = ::WinsRecordAction(&pRecAction);
  2538. #endif WINS_CLIENT_APIS
  2539. if (dwLastStatus != ERROR_SUCCESS)
  2540. {
  2541. }
  2542. else
  2543. {
  2544. // query the server for correct info
  2545. PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
  2546. if (pRecAction1 == NULL)
  2547. {
  2548. hr = AddToLocalStorage(pRecAction, pNode);
  2549. }
  2550. else
  2551. {
  2552. // the record found and correct info displayed
  2553. //add it to the m_spWinsDatabase
  2554. hr = AddToLocalStorage(pRecAction1, pNode);
  2555. free(pRecAction1->pName);
  2556. }
  2557. }
  2558. }
  2559. else
  2560. {
  2561. //
  2562. // NOTICE:: When lanman compatible, the name is added
  2563. // three times - once each as worksta, server
  2564. // and messenger. This will change when we allow
  2565. // different 16th bytes to be set.
  2566. //
  2567. if (IsLanManCompatible() && !fEdit)
  2568. {
  2569. BYTE ab[] = { 0x00, 0x03, 0x20 };
  2570. ::memset(RecAction.pName + nLen, (int)' ', 16-nLen);
  2571. int i;
  2572. for (i = 0; i < sizeof(ab) / sizeof(ab[0]); ++i)
  2573. {
  2574. *(RecAction.pName+15) = ab[i];
  2575. *(RecAction.pName+16) = '\0';
  2576. RecAction.NameLen = nLen = 16;
  2577. // append the scope name here, if present
  2578. if (!m_strStaticMappingScope.IsEmpty())
  2579. {
  2580. // don't allow the scope to be appended if the 16th char is 00,
  2581. // consistent with WinsCL
  2582. if (i != 0)
  2583. {
  2584. char *lpAppend = new char [MAX_PATH];
  2585. AppendScopeName((LPSTR)RecAction.pName, (LPSTR)lpAppend);
  2586. strcpy((LPSTR)RecAction.pName, (LPSTR)lpAppend);
  2587. RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
  2588. delete [] lpAppend;
  2589. }
  2590. }
  2591. pRecAction = &RecAction;
  2592. #ifdef WINS_CLIENT_APIS
  2593. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
  2594. #else
  2595. dwLastStatus = ::WinsRecordAction(&pRecAction);
  2596. #endif WINS_CLIENT_APIS
  2597. Trace1("WinsRecAction suceeded for '%lx'\n", ab[i]);
  2598. if (dwLastStatus != ERROR_SUCCESS)
  2599. {
  2600. break;
  2601. }
  2602. else
  2603. {
  2604. // query the server for correct info
  2605. PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
  2606. if (pRecAction1 == NULL)
  2607. {
  2608. //add it to the m_spWinsDatabase
  2609. hr = AddToLocalStorage(pRecAction, pNode);
  2610. }
  2611. else
  2612. {
  2613. // the record found and correct info displayed
  2614. //add it to the m_spWinsDatabase
  2615. hr = AddToLocalStorage(pRecAction1, pNode);
  2616. free(pRecAction1->pName);
  2617. }
  2618. }
  2619. }
  2620. }
  2621. else
  2622. {
  2623. ::memset(RecAction.pName+nLen, (int)'\0',16-nLen);
  2624. *(RecAction.pName+15) = 0x20;
  2625. *(RecAction.pName+16) = '\0';
  2626. RecAction.NameLen = nLen;
  2627. char szAppend[MAX_PATH];
  2628. if (!m_strStaticMappingScope.IsEmpty())
  2629. {
  2630. AppendScopeName((LPSTR)RecAction.pName, (LPSTR)szAppend);
  2631. strcpy((LPSTR)RecAction.pName, (LPSTR)szAppend);
  2632. RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
  2633. }
  2634. #ifdef WINS_CLIENT_APIS
  2635. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
  2636. #else
  2637. dwLastStatus = ::WinsRecordAction(&pRecAction);
  2638. #endif WINS_CLIENT_APIS
  2639. if (dwLastStatus != ERROR_SUCCESS)
  2640. {
  2641. }
  2642. else
  2643. {
  2644. // query the server for correct info
  2645. PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
  2646. if (pRecAction1 == NULL)
  2647. {
  2648. //add it to the m_spWinsDatabase
  2649. hr = AddToLocalStorage(pRecAction, pNode);
  2650. }
  2651. else
  2652. {
  2653. // the record found and correct info displayed
  2654. //add it to the m_spWinsDatabase
  2655. hr = AddToLocalStorage(pRecAction1, pNode);
  2656. free(pRecAction1->pName);
  2657. }
  2658. }
  2659. }
  2660. }
  2661. }
  2662. else
  2663. {
  2664. RecAction.NameLen = nLen;
  2665. #ifdef WINS_CLIENT_APIS
  2666. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
  2667. #else
  2668. dwLastStatus = ::WinsRecordAction(&pRecAction);
  2669. #endif WINS_CLIENT_APIS
  2670. if (dwLastStatus != ERROR_SUCCESS)
  2671. {
  2672. }
  2673. else
  2674. {
  2675. // query the server for correct info
  2676. PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
  2677. if (pRecAction1 == NULL)
  2678. {
  2679. //add it to the m_spWinsDatabase
  2680. hr = AddToLocalStorage(pRecAction, pNode);
  2681. }
  2682. else
  2683. {
  2684. // the record found and correct info displayed
  2685. //add it to the m_spWinsDatabase
  2686. hr = AddToLocalStorage(pRecAction1, pNode);
  2687. free(pRecAction1->pName);
  2688. }
  2689. }
  2690. }
  2691. if (RecAction.pName != NULL)
  2692. {
  2693. ::WinsFreeMem(RecAction.pName);
  2694. }
  2695. if (RecAction.pAdd != NULL)
  2696. {
  2697. ::WinsFreeMem(RecAction.pAdd);
  2698. }
  2699. return dwLastStatus;
  2700. }
  2701. /*---------------------------------------------------------------------------
  2702. CActiveRegistrationsHandler::AddToLocalStorage(
  2703. PWINSINTF_RECORD_ACTION_T pRecAction,
  2704. ITFSNode* pNode
  2705. )
  2706. add it to the m_spWinsDatabase, after getting all the information(Version, Exp etc)
  2707. from the server
  2708. Author: v-shubk
  2709. ---------------------------------------------------------------------------*/
  2710. HRESULT
  2711. CActiveRegistrationsHandler::AddToLocalStorage(PWINSINTF_RECORD_ACTION_T pRecAction,
  2712. ITFSNode* pNode)
  2713. {
  2714. HRESULT hr = hrOK;
  2715. BOOL bIPOk = FALSE;
  2716. WinsRecord ws;
  2717. // convert WINS_RECORD_ACTION to internal record
  2718. WinsIntfToWinsRecord(pRecAction, ws);
  2719. if (pRecAction->OwnerId < (UINT) m_pServerInfoArray->GetSize())
  2720. ws.dwOwner = (*m_pServerInfoArray)[pRecAction->OwnerId].m_dwIp;
  2721. if (m_spWinsDatabase)
  2722. {
  2723. hr = m_spWinsDatabase->AddRecord(&ws);
  2724. }
  2725. return hr;
  2726. }
  2727. /*---------------------------------------------------------------------------
  2728. CActiveRegistrationsHandler::OnImportLMHOSTS(ITFSNode* pNode)
  2729. Command Handler for Import LMHosts
  2730. Author: v-shubk
  2731. ---------------------------------------------------------------------------*/
  2732. HRESULT
  2733. CActiveRegistrationsHandler::OnImportLMHOSTS(ITFSNode* pNode)
  2734. {
  2735. HRESULT hr = hrOK;
  2736. CString strTitle;
  2737. CString strFilter;
  2738. strFilter.LoadString(IDS_ALL_FILES);
  2739. // put up the file dlg to get the file
  2740. CFileDialog dlgFile(TRUE,
  2741. NULL,
  2742. NULL,
  2743. OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
  2744. strFilter);
  2745. CThemeContextActivator themeActivator;
  2746. dlgFile.m_ofn.lpstrTitle = strTitle;
  2747. DWORD err = ERROR_SUCCESS;
  2748. if (dlgFile.DoModal() == IDOK)
  2749. {
  2750. //
  2751. // If this is a local connection, we copy the file to
  2752. // temporary name (the source may be on a remote drive
  2753. // which is not accessible to the WINS service.
  2754. //
  2755. // If this is not a local connection, attempt to copy
  2756. // the file to a temp name on C$ of the WINS server
  2757. //
  2758. BEGIN_WAIT_CURSOR
  2759. CString strMappingFile(dlgFile.GetPathName());
  2760. do
  2761. {
  2762. if (IsLocalConnection(pNode))
  2763. {
  2764. CString strWins;
  2765. strWins.LoadString(IDS_WINS);
  2766. CString strTmpFile(_tempnam(NULL, "WINS"));
  2767. //
  2768. // First copy file to a temporary name (since the file
  2769. // could be remote), and then import and delete this file
  2770. //
  2771. if (!CopyFile(strMappingFile, strTmpFile, TRUE) ||
  2772. !SetFileAttributes(strTmpFile, FILE_ATTRIBUTE_NORMAL))
  2773. {
  2774. err = ::GetLastError();
  2775. break;
  2776. }
  2777. //
  2778. // Now import the temporary file, and delete the file
  2779. // afterwards.
  2780. //
  2781. err = ImportStaticMappingsFile(pNode, strTmpFile, TRUE);
  2782. }
  2783. else
  2784. {
  2785. //
  2786. // Try copying to the remote machine C: drive
  2787. //
  2788. CString strServerName;
  2789. GetServerName(pNode, strServerName);
  2790. CString strWins;
  2791. strWins.LoadString(IDS_WINS);
  2792. CString strTemp;
  2793. strTemp.Format(_T("\\\\%s\\C$"), strServerName);
  2794. // Find a suitable remote file name
  2795. CString strRemoteFile;
  2796. DWORD dwErr = RemoteTmp(strTemp, strWins, strRemoteFile);
  2797. if (dwErr != ERROR_SUCCESS)
  2798. {
  2799. CString strError, strMessage;
  2800. ::GetSystemMessage(dwErr, strError.GetBuffer(1024), 1024);
  2801. strError.ReleaseBuffer();
  2802. AfxFormatString1(strMessage, IDS_ERR_REMOTE_IMPORT, strError);
  2803. AfxMessageBox(strMessage);
  2804. goto Error;
  2805. }
  2806. //
  2807. // First copy file to a temporary name (since the file
  2808. // could be remote), and then import and delete this file
  2809. //
  2810. if (!CopyFile(strMappingFile, strRemoteFile, TRUE) ||
  2811. !SetFileAttributes(strRemoteFile, FILE_ATTRIBUTE_NORMAL))
  2812. {
  2813. err = ::GetLastError();
  2814. break;
  2815. }
  2816. //
  2817. // fixup the filename so it looks local to the wins server
  2818. //
  2819. LPTSTR pch = strRemoteFile.GetBuffer(256);
  2820. //
  2821. // Now replace the remote path with a local path
  2822. // for the remote WINS server
  2823. //
  2824. while (*pch != '$')
  2825. {
  2826. ++pch;
  2827. }
  2828. *pch = ':';
  2829. --pch;
  2830. CString strRemoteFileNew(pch);
  2831. strRemoteFile.ReleaseBuffer();
  2832. //
  2833. // Now import the temporary file, and delete the file
  2834. // afterwards.
  2835. //
  2836. err = ImportStaticMappingsFile(pNode, strRemoteFileNew, TRUE);
  2837. }
  2838. }
  2839. while(FALSE);
  2840. END_WAIT_CURSOR
  2841. if (err == ERROR_SUCCESS)
  2842. {
  2843. AfxMessageBox(IDS_MSG_IMPORT, MB_ICONINFORMATION);
  2844. // refresh the result pane now.
  2845. RefreshResults(pNode);
  2846. }
  2847. else
  2848. {
  2849. ::WinsMessageBox(err, MB_OK);
  2850. }
  2851. // refresh the server statistics
  2852. SPITFSNode spServerNode;
  2853. pNode->GetParent(&spServerNode);
  2854. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  2855. // rferesh the statistics
  2856. pServer->GetStatistics(spServerNode, NULL);
  2857. }
  2858. Error:
  2859. return err;
  2860. }
  2861. /*---------------------------------------------------------------------------
  2862. CActiveRegistrationsHandler::IsLocalConnection(ITFSNode *pNode)
  2863. Check if the loacl machine is being managed
  2864. Author: v-shubk
  2865. ---------------------------------------------------------------------------*/
  2866. BOOL
  2867. CActiveRegistrationsHandler::IsLocalConnection(ITFSNode *pNode)
  2868. {
  2869. // get the server netbios name
  2870. CString strServerName;
  2871. GetServerName(pNode,strServerName);
  2872. // address of name buffer
  2873. TCHAR szBuffer[MAX_COMPUTERNAME_LENGTH + 1];
  2874. DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1 ;
  2875. ::GetComputerName(szBuffer, &nSize);
  2876. CString strCompName(szBuffer);
  2877. if (strCompName == strServerName)
  2878. {
  2879. return TRUE;
  2880. }
  2881. return FALSE;
  2882. }
  2883. /*---------------------------------------------------------------------------
  2884. CActiveRegistrationsHandler::GetServerName(ITFSNode * pNode,
  2885. CString &strServerName)
  2886. Talk to the parent node and get the server name
  2887. we are managing
  2888. Author: v-shubk
  2889. ---------------------------------------------------------------------------*/
  2890. void
  2891. CActiveRegistrationsHandler::GetServerName(ITFSNode * pNode,
  2892. CString &strServerName)
  2893. {
  2894. SPITFSNode spServerNode;
  2895. pNode->GetParent(&spServerNode);
  2896. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  2897. strServerName = pServer->GetServerAddress();
  2898. }
  2899. /*---------------------------------------------------------------------------
  2900. CActiveRegistrationsHandler::ImportStaticMappingsFile(CString strFile,
  2901. BOOL fDelete)
  2902. Call the WINS API to import the statis mappings text file
  2903. Author: v-shubk
  2904. ---------------------------------------------------------------------------*/
  2905. HRESULT
  2906. CActiveRegistrationsHandler::ImportStaticMappingsFile(ITFSNode *pNode,
  2907. CString strFile,
  2908. BOOL fDelete)
  2909. {
  2910. HRESULT hr = hrOK;
  2911. SPITFSNode spServerNode;
  2912. pNode->GetParent(&spServerNode);
  2913. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  2914. LPTSTR lpszTemp = strFile.GetBuffer(MAX_PATH * 2);
  2915. #ifdef WINS_CLIENT_APIS
  2916. DWORD dwLastStatus = ::WinsDoStaticInit(pServer->GetBinding(),
  2917. (LPTSTR)lpszTemp,
  2918. fDelete);
  2919. #else
  2920. DWORD dwLastStatus = ::WinsDoStaticInit((LPTSTR)lpszTemp, fDelete);
  2921. #endif WINS_CLIENT_APIS
  2922. strFile.ReleaseBuffer();
  2923. return dwLastStatus;
  2924. }
  2925. /*---------------------------------------------------------------------------
  2926. CActiveRegistrationsHandler::RemoteTmp(CString strDir,CString strPrefix )
  2927. Get a temporary file on a remote drive
  2928. Author: v-shubk
  2929. ---------------------------------------------------------------------------*/
  2930. DWORD
  2931. CActiveRegistrationsHandler::RemoteTmp(CString & strDir, CString & strPrefix, CString & strRemoteFile)
  2932. {
  2933. DWORD dwErr = ERROR_SUCCESS;
  2934. CString strReturn;
  2935. int n = 0;
  2936. while (TRUE)
  2937. {
  2938. strReturn.Format(_T("%s\\%s%d"), strDir, strPrefix, ++n);
  2939. if (GetFileAttributes(strReturn) == -1)
  2940. {
  2941. dwErr = GetLastError();
  2942. if (dwErr == ERROR_FILE_NOT_FOUND)
  2943. {
  2944. strRemoteFile = strReturn;
  2945. dwErr = ERROR_SUCCESS;
  2946. }
  2947. break;
  2948. }
  2949. }
  2950. return dwErr;
  2951. }
  2952. /*---------------------------------------------------------------------------
  2953. CActiveRegistrationsHandler::DeleteMappingFromServer(ITFSComponent * pComponent,
  2954. WinsRecord *pws,int nIndex)
  2955. Deletes wins record from the Wins Server
  2956. Author: v-shubk
  2957. ---------------------------------------------------------------------------*/
  2958. DWORD
  2959. CActiveRegistrationsHandler::DeleteMappingFromServer
  2960. (
  2961. ITFSComponent * pComponent,
  2962. WinsRecord * pws,
  2963. int nIndex
  2964. )
  2965. {
  2966. HRESULT hr = hrOK;
  2967. //check if the record is static
  2968. WINSINTF_RECORD_ACTION_T RecAction;
  2969. PWINSINTF_RECORD_ACTION_T pRecAction;
  2970. ZeroMemory(&RecAction, sizeof(RecAction));
  2971. SPITFSNode spNode;
  2972. pComponent->GetSelectedNode(&spNode);
  2973. SPITFSNode spParentNode;
  2974. spNode->GetParent(&spParentNode);
  2975. CWinsServerHandler* pServer = GETHANDLER(CWinsServerHandler, spParentNode);
  2976. if (pws->dwState & WINSDB_REC_STATIC)
  2977. {
  2978. RecAction.fStatic = TRUE;
  2979. if (pws->dwState & WINSDB_REC_UNIQUE)
  2980. {
  2981. RecAction.TypOfRec_e = WINSINTF_E_UNIQUE;
  2982. }
  2983. else
  2984. if (pws->dwState & WINSDB_REC_SPEC_GROUP)
  2985. {
  2986. RecAction.TypOfRec_e = WINSINTF_E_SPEC_GROUP;
  2987. }
  2988. else
  2989. if (pws->dwState & WINSDB_REC_NORM_GROUP)
  2990. {
  2991. RecAction.TypOfRec_e = WINSINTF_E_NORM_GROUP;
  2992. }
  2993. else
  2994. if (pws->dwState & WINSDB_REC_MULTIHOMED)
  2995. {
  2996. RecAction.TypOfRec_e = WINSINTF_E_MULTIHOMED;
  2997. }
  2998. }
  2999. else
  3000. {
  3001. RecAction.fStatic = FALSE;
  3002. }
  3003. RecAction.Cmd_e = WINSINTF_E_DELETE;
  3004. RecAction.State_e = WINSINTF_E_DELETED;
  3005. RecAction.pName = NULL;
  3006. RecAction.pAdd = NULL;
  3007. pRecAction = &RecAction;
  3008. RecAction.pName = (LPBYTE)::WinsAllocMem(pws->dwNameLen+1);
  3009. if (RecAction.pName == NULL)
  3010. {
  3011. return ::GetLastError();
  3012. }
  3013. ZeroMemory(RecAction.pName, pws->dwNameLen+1);
  3014. memcpy(RecAction.pName, pws->szRecordName, pws->dwNameLen);
  3015. if (pws->dwNameLen)
  3016. {
  3017. RecAction.NameLen = pws->dwNameLen;
  3018. }
  3019. else
  3020. {
  3021. RecAction.NameLen = ::strlen((LPSTR)RecAction.pName);
  3022. }
  3023. RecAction.OwnerId = pws->dwOwner;
  3024. DWORD dwLastStatus = ERROR_SUCCESS;
  3025. #ifdef WINS_CLIENT_APIS
  3026. dwLastStatus = ::WinsRecordAction(pServer->GetBinding(), &pRecAction);
  3027. #else
  3028. dwLastStatus = ::WinsRecordAction(&pRecAction);
  3029. #endif WINS_CLIENT_APIS
  3030. if (RecAction.pName != NULL)
  3031. {
  3032. ::WinsFreeMem(RecAction.pName);
  3033. }
  3034. if (RecAction.pAdd != NULL)
  3035. {
  3036. ::WinsFreeMem(RecAction.pAdd);
  3037. }
  3038. return dwLastStatus;
  3039. }
  3040. /*---------------------------------------------------------------------------
  3041. CActiveRegistrationsHandler::EditMapping(ITFSNode *pNode)
  3042. Edit the already mapping , the user might have changed the IP address
  3043. Author: v-shubk
  3044. ---------------------------------------------------------------------------*/
  3045. HRESULT
  3046. CActiveRegistrationsHandler::EditMapping(ITFSNode *pNode,
  3047. ITFSComponent *pComponent,
  3048. int nIndex)
  3049. {
  3050. HRESULT hr = hrOK;
  3051. DWORD err = ERROR_SUCCESS;
  3052. int i;
  3053. int nCurrentCount;
  3054. // get the server
  3055. SPITFSNode spServerNode;
  3056. pNode->GetParent(&spServerNode);
  3057. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  3058. BOOL fInternetGroup = FALSE;
  3059. if (m_strStaticMappingType.CompareNoCase(g_strStaticTypeInternetGroup) == 0)
  3060. {
  3061. fInternetGroup = TRUE;
  3062. }
  3063. // create the multiple IPNamePr
  3064. if (pServer->IsValidNetBIOSName(m_strStaticMappingName, IsLanManCompatible(), FALSE))
  3065. {
  3066. m_Multiples.SetNetBIOSName(m_strStaticMappingName);
  3067. m_Multiples.SetNetBIOSNameLength(m_strStaticMappingName.GetLength());
  3068. int nMappings = 0;
  3069. int i;
  3070. switch(m_nStaticMappingType)
  3071. {
  3072. case WINSINTF_E_UNIQUE:
  3073. case WINSINTF_E_NORM_GROUP:
  3074. {
  3075. nMappings = 1;
  3076. LONG l;
  3077. m_Multiples.SetIpAddress(m_lArrayIPAddress.GetAt(0));
  3078. }
  3079. break;
  3080. case WINSINTF_E_SPEC_GROUP:
  3081. case WINSINTF_E_MULTIHOMED:
  3082. nMappings = (int)m_lArrayIPAddress.GetSize();
  3083. ASSERT(nMappings <= WINSINTF_MAX_MEM);
  3084. if (!fInternetGroup && nMappings == 0)
  3085. {
  3086. //return E_FAIL;
  3087. }
  3088. for (i = 0; i < nMappings; ++i)
  3089. {
  3090. m_Multiples.SetIpAddress(i,m_lArrayIPAddress.GetAt(i) );
  3091. }
  3092. break;
  3093. default:
  3094. ASSERT(0 && "Invalid mapping type!");
  3095. }
  3096. HROW hrowDel;
  3097. WinsRecord ws;
  3098. // from internal storage
  3099. CORg(m_spWinsDatabase->GetHRow(m_nSelectedIndex, &hrowDel));
  3100. CORg(m_spWinsDatabase->GetData(hrowDel, &ws));
  3101. if (m_nStaticMappingType == WINSINTF_E_SPEC_GROUP ||
  3102. m_nStaticMappingType == WINSINTF_E_MULTIHOMED)
  3103. {
  3104. //
  3105. // An internet group being edited cannot simply be
  3106. // re-added, since it will add ip addresses, not
  3107. // overwrite them, so it must first be removed.
  3108. //
  3109. err = DeleteMappingFromServer(pComponent, &ws, m_nSelectedIndex);
  3110. }
  3111. //
  3112. // We edit the mapping by merely re-adding it, which
  3113. // has the same effect.
  3114. //
  3115. if (err == ERROR_SUCCESS)
  3116. {
  3117. err = EditMappingToServer(pNode,
  3118. m_nStaticMappingType,
  3119. nMappings,
  3120. m_Multiples,
  3121. TRUE,
  3122. &m_CurrentRecord);
  3123. }
  3124. if (err != ERROR_SUCCESS)
  3125. {
  3126. return err;
  3127. }
  3128. WINSINTF_ADD_T OwnAdd;
  3129. //
  3130. // Fill in current owner
  3131. //
  3132. OwnAdd.Len = 4;
  3133. OwnAdd.Type = 0;
  3134. OwnAdd.IPAdd = pServer->GetServerIP();
  3135. WINSINTF_RECS_T Recs;
  3136. Recs.pRow = NULL;
  3137. #ifdef WINS_CLIENT_APIS
  3138. err = ::WinsGetDbRecsByName(pServer->GetBinding(),
  3139. &OwnAdd,
  3140. WINSINTF_BEGINNING,
  3141. (LPBYTE) ws.szRecordName,
  3142. ws.dwNameLen,
  3143. 1,
  3144. (ws.dwState & WINSDB_REC_STATIC)
  3145. ? WINSINTF_STATIC : WINSINTF_DYNAMIC,
  3146. &Recs);
  3147. #else
  3148. err = ::WinsGetDbRecsByName(&OwnAdd,
  3149. WINSINTF_BEGINNING,
  3150. (LPBYTE) ws.szRecordName,
  3151. ws.dwNameLen,
  3152. 1,
  3153. (ws.dwState & WINSDB_REC_STATIC)
  3154. ? WINSINTF_STATIC : WINSINTF_DYNAMIC,
  3155. &Recs);
  3156. #endif WINS_CLIENT_APIS
  3157. if (err == ERROR_SUCCESS)
  3158. {
  3159. TRY
  3160. {
  3161. ASSERT(Recs.NoOfRecs == 1);
  3162. if (Recs.NoOfRecs == 0)
  3163. {
  3164. //
  3165. // the record can not be found.
  3166. // This should not happen!
  3167. //
  3168. //Trace("Unable to find the record to refresh:\n");
  3169. return ERROR_REC_NON_EXISTENT;
  3170. }
  3171. PWINSINTF_RECORD_ACTION_T pRow1 = Recs.pRow;
  3172. WinsRecord wRecord;
  3173. WinsIntfToWinsRecord(pRow1, wRecord);
  3174. if (pRow1->OwnerId < (UINT) m_pServerInfoArray->GetSize())
  3175. wRecord.dwOwner = (*m_pServerInfoArray)[pRow1->OwnerId].m_dwIp;
  3176. // RefreshData(Recs.pRow), delete this particular record and add it again;
  3177. // from internal storage
  3178. CORg(m_spWinsDatabase->DeleteRecord(hrowDel));
  3179. CORg(m_spWinsDatabase->AddRecord(&wRecord));
  3180. // now set the count.. this effectively redraws the contents
  3181. CORg (m_pCurrentDatabase->GetCurrentCount(&nCurrentCount));
  3182. UpdateCurrentView(pNode);
  3183. }
  3184. CATCH_ALL(e)
  3185. {
  3186. return ::GetLastError();
  3187. }
  3188. END_CATCH_ALL;
  3189. }
  3190. if (Recs.pRow != NULL)
  3191. {
  3192. ::WinsFreeMem(Recs.pRow);
  3193. }
  3194. }
  3195. Error:
  3196. return err;
  3197. }
  3198. /*---------------------------------------------------------------------------
  3199. CActiveRegistrationsHandler::QueryForName()
  3200. queries WINS server given the name and gets info to be displayed in the
  3201. result pane
  3202. Author: v-shubk
  3203. ---------------------------------------------------------------------------*/
  3204. PWINSINTF_RECORD_ACTION_T
  3205. CActiveRegistrationsHandler::QueryForName
  3206. (
  3207. ITFSNode * pNode,
  3208. PWINSINTF_RECORD_ACTION_T pRecAction,
  3209. BOOL fStatic
  3210. )
  3211. {
  3212. SPITFSNode spNode;
  3213. pNode->GetParent(&spNode);
  3214. CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spNode);
  3215. HRESULT hr = hrOK;
  3216. pRecAction->pAdd = NULL;
  3217. pRecAction->NoOfAdds = 0;
  3218. pRecAction->fStatic = fStatic;
  3219. pRecAction->Cmd_e = WINSINTF_E_QUERY;
  3220. #ifdef WINS_CLIENT_APIS
  3221. DWORD dwStatus = WinsRecordAction(pServer->GetBinding(), &pRecAction);
  3222. #else
  3223. DWORD dwStatus = WinsRecordAction(&pRecAction);
  3224. #endif WINS_CLIENT_APIS
  3225. // when we query for a record, the string length must not include the null terminator.
  3226. // in the normal case using GetDbRecs, wins returns the name length as length + 1
  3227. // for the null terminator. Since all of the code expects any WINSINTFS_RECORD_ACTION_T
  3228. // struct to be in that format, let's touch things up a bit and make a copy.
  3229. if (dwStatus == 0)
  3230. {
  3231. pRecAction->NameLen++;
  3232. LPBYTE pNew = (LPBYTE) malloc(pRecAction->NameLen);
  3233. if (pNew)
  3234. {
  3235. ZeroMemory(pNew, pRecAction->NameLen);
  3236. memcpy(pNew, pRecAction->pName, pRecAction->NameLen - 1);
  3237. pRecAction->pName = pNew;
  3238. }
  3239. return pRecAction;
  3240. }
  3241. else
  3242. {
  3243. return NULL;
  3244. }
  3245. }
  3246. /*---------------------------------------------------------------------------
  3247. CActiveRegistrationsHandler::ToString(DWORD dwParam, CString& strParam)
  3248. converts DWORD to CString
  3249. Author v-shubk
  3250. ---------------------------------------------------------------------------*/
  3251. void
  3252. CActiveRegistrationsHandler::ToString(DWORD dwParam, CString& strParam)
  3253. {
  3254. TCHAR szStr[20];
  3255. _ltot((LONG)dwParam, szStr, 10);
  3256. CString str(szStr);
  3257. strParam = str;
  3258. }
  3259. /*---------------------------------------------------------------------------
  3260. CActiveRegistrationsHandler::OnExportEntries()
  3261. Command Handler for Export Database
  3262. Author v-shubk
  3263. ---------------------------------------------------------------------------*/
  3264. HRESULT
  3265. CActiveRegistrationsHandler::OnExportEntries()
  3266. {
  3267. HRESULT hr = hrOK;
  3268. WinsRecord ws;
  3269. HROW hrow;
  3270. if (!m_pCurrentDatabase)
  3271. {
  3272. return NULL;
  3273. }
  3274. // Bring up the Save Dialog
  3275. CString strType;
  3276. strType.LoadString(IDS_FILE_EXTENSION);
  3277. CString strDefFileName;
  3278. strDefFileName.LoadString(IDS_FILE_DEFNAME);
  3279. CString strFilter;
  3280. strFilter.LoadString(IDS_STR_EXPORTFILE_FILTER);
  3281. // put up the dlg to get the file name
  3282. CFileDialog cFileDlg(FALSE,
  3283. strType,
  3284. strDefFileName,
  3285. OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
  3286. strFilter);
  3287. CThemeContextActivator themeActivator;
  3288. CString strTitle;
  3289. strTitle.LoadString(IDS_EXPFILE_TITLE);
  3290. cFileDlg.m_ofn.lpstrTitle = strTitle;
  3291. if ( cFileDlg.DoModal() != IDOK )
  3292. {
  3293. return hrFalse;
  3294. }
  3295. // getthe entire path
  3296. CString strFileName = cFileDlg.GetPathName();
  3297. COM_PROTECT_TRY
  3298. {
  3299. int nCount;
  3300. m_pCurrentDatabase->GetCurrentCount(&nCount);
  3301. CString strContent;
  3302. strContent.Empty();
  3303. CString strTemp;
  3304. strTemp.Empty();
  3305. CString strLine;
  3306. strLine.Empty();
  3307. CString strDelim = _T(',');
  3308. CString strNewLine = _T("\r\n");
  3309. // create a file named "WinsExp.txt" in the current directory
  3310. CFile cFileExp(strFileName,
  3311. CFile::modeCreate | CFile::modeRead | CFile::modeWrite);
  3312. // this is a unicode file, write the unicde lead bytes (2)
  3313. cFileExp.Write(&gwUnicodeHeader, sizeof(WORD));
  3314. CString strHead;
  3315. strHead.LoadString(IDS_STRING_HEAD);
  3316. strHead += strNewLine;
  3317. cFileExp.Write(strHead, strHead.GetLength()*sizeof(TCHAR));
  3318. BEGIN_WAIT_CURSOR
  3319. #ifdef DEBUG
  3320. CTime timeStart, timeFinish;
  3321. timeStart = CTime::GetCurrentTime();
  3322. #endif
  3323. for (int i = 0; i < nCount; i++)
  3324. {
  3325. strLine.Empty();
  3326. strTemp.Empty();
  3327. hr = m_pCurrentDatabase->GetHRow(i, &hrow);
  3328. hr = m_pCurrentDatabase->GetData(hrow, &ws);
  3329. // build the name string
  3330. CleanNetBIOSName(ws.szRecordName, // input char *
  3331. strTemp, // output LPTSTR
  3332. TRUE, // Expand
  3333. TRUE, // Truncate
  3334. IsLanManCompatible(),
  3335. TRUE, // name is OEM
  3336. FALSE, // No double backslash
  3337. ws.dwNameLen);
  3338. strLine += strTemp;
  3339. strLine += strDelim;
  3340. // now the type
  3341. m_NameTypeMap.TypeToCString((DWORD)ws.szRecordName[15], MAKELONG(HIWORD(ws.dwType), 0), strTemp);
  3342. strLine += strTemp;
  3343. strLine += strDelim;
  3344. // IP address
  3345. if ( (ws.dwState & WINSDB_REC_UNIQUE) ||
  3346. (ws.dwState & WINSDB_REC_NORM_GROUP) )
  3347. {
  3348. MakeIPAddress(ws.dwIpAdd[0], strTemp);
  3349. strLine += strTemp;
  3350. }
  3351. else
  3352. {
  3353. CString strTemp2;
  3354. // this record has multiple addresses. The addresses are in the form of:
  3355. // owner wins, then IP address
  3356. // out put will look like address - owner IP;address - owner ip
  3357. for (DWORD i = 0; i < ws.dwNoOfAddrs; i++)
  3358. {
  3359. if (i != 0)
  3360. strLine += _T(";");
  3361. // owner
  3362. ::MakeIPAddress(ws.dwIpAdd[i++], strTemp);
  3363. // actual address
  3364. ::MakeIPAddress(ws.dwIpAdd[i], strTemp2);
  3365. strTemp2 += _T(" - ");
  3366. strTemp2 += strTemp;
  3367. strLine += strTemp2;
  3368. }
  3369. }
  3370. strLine += strDelim;
  3371. // active status
  3372. GetStateString(ws.dwState, strTemp);
  3373. strLine += strTemp;
  3374. strLine += strDelim;
  3375. // static flag
  3376. if (ws.dwState & WINSDB_REC_STATIC)
  3377. strTemp.LoadString(IDS_ACTIVEREG_STATIC);
  3378. else
  3379. strTemp = _T("");
  3380. strLine += strTemp;
  3381. strLine += strDelim;
  3382. // version
  3383. GetVersionInfo(ws.liVersion.LowPart, ws.liVersion.HighPart, strTemp);
  3384. strLine += strTemp;
  3385. strLine += strDelim;
  3386. // expiration time
  3387. if (ws.dwExpiration == INFINITE_EXPIRATION)
  3388. {
  3389. Verify(strTemp.LoadString(IDS_INFINITE));
  3390. }
  3391. else
  3392. {
  3393. strTemp = TMST(ws.dwExpiration);
  3394. }
  3395. strLine += strTemp;
  3396. strLine += strNewLine;
  3397. strContent += strLine;
  3398. //optimize
  3399. // write to the file for every 1000 records converted
  3400. if ( i % 1000 == 0)
  3401. {
  3402. cFileExp.Write(strContent, strContent.GetLength() * (sizeof(TCHAR)) );
  3403. cFileExp.SeekToEnd();
  3404. // clear all the strings now
  3405. strContent.Empty();
  3406. }
  3407. }
  3408. // write to the file
  3409. cFileExp.Write(strContent, strContent.GetLength() * (sizeof(TCHAR)) );
  3410. cFileExp.Close();
  3411. #ifdef DEBUG
  3412. timeFinish = CTime::GetCurrentTime();
  3413. CTimeSpan timeDelta = timeFinish - timeStart;
  3414. CString strTempTime = timeDelta.Format(_T("%H:%M:%S"));
  3415. Trace2("WINS DB - Export Entries: %d records read, total time %s\n", i, strTempTime);
  3416. #endif
  3417. END_WAIT_CURSOR
  3418. }
  3419. COM_PROTECT_CATCH
  3420. CString strDisp;
  3421. AfxFormatString1(strDisp, IDS_EXPORT_SUCCESS, strFileName);
  3422. AfxMessageBox(strDisp, MB_ICONINFORMATION );
  3423. return hr;
  3424. }
  3425. /*---------------------------------------------------------------------------
  3426. CActiveRegistrationsHandler::BuildOwnerArray(ITFSNode *pNode)
  3427. Builds the list of owners in the server
  3428. Author: v-shubk
  3429. ---------------------------------------------------------------------------*/
  3430. HRESULT
  3431. CActiveRegistrationsHandler::BuildOwnerArray(handle_t hBinding)
  3432. {
  3433. HRESULT hr = hrOK;
  3434. DWORD err = 0;
  3435. CWinsResults winsResults;
  3436. err = winsResults.Update(hBinding);
  3437. if (err == ERROR_SUCCESS)
  3438. {
  3439. m_pServerInfoArray->RemoveAll();
  3440. LARGE_INTEGER liVersion;
  3441. DWORD dwIP;
  3442. CString strName;
  3443. BOOL fGetHostName = TRUE;
  3444. for (int i = 0; i < winsResults.AddVersMaps.GetSize(); i++)
  3445. {
  3446. liVersion = winsResults.AddVersMaps[i].VersNo;
  3447. dwIP = winsResults.AddVersMaps[i].Add.IPAdd;
  3448. CServerInfo serverInfo(dwIP, strName, liVersion);
  3449. int nIndex = (int)m_pServerInfoArray->Add(serverInfo);
  3450. }
  3451. }
  3452. return HRESULT_FROM_WIN32(err);
  3453. }
  3454. /*---------------------------------------------------------------------------
  3455. CActiveRegistrationsHandler::OnCheckRegNames(ITFSNode* pNode)
  3456. Command Handler for Check Registered names
  3457. Author: v-shubk
  3458. ---------------------------------------------------------------------------*/
  3459. HRESULT
  3460. CActiveRegistrationsHandler::OnCheckRegNames(ITFSNode* pNode)
  3461. {
  3462. HRESULT hr = hrOK;
  3463. CCheckRegNames dlgRegName;
  3464. CThemeContextActivator themeActivator;
  3465. if (IDOK != dlgRegName.DoModal())
  3466. {
  3467. return hr;
  3468. }
  3469. CCheckNamesProgress dlgCheckNames;
  3470. dlgCheckNames.m_strNameArray.Copy(dlgRegName.m_strNameArray);
  3471. dlgCheckNames.m_strServerArray.Copy(dlgRegName.m_strServerArray);
  3472. dlgCheckNames.m_fVerifyWithPartners = dlgRegName.m_fVerifyWithPartners;
  3473. dlgCheckNames.DoModal();
  3474. return hr;
  3475. }
  3476. /*---------------------------------------------------------------------------
  3477. CActiveRegistrationsHandler::OnDeleteOwner(ITFSNode* pNode)
  3478. Command Handler for Tombstone all records
  3479. Author: EricDav
  3480. ---------------------------------------------------------------------------*/
  3481. HRESULT
  3482. CActiveRegistrationsHandler::OnDeleteOwner(ITFSNode* pNode)
  3483. {
  3484. HRESULT hr = hrOK;
  3485. CDeleteOwner dlgDeleteOwner(pNode);
  3486. CThemeContextActivator themeActivator;
  3487. DWORD dwErr, dwIp;
  3488. CString strText, strIp;
  3489. if (dlgDeleteOwner.DoModal() == IDOK)
  3490. {
  3491. BEGIN_WAIT_CURSOR
  3492. if (dlgDeleteOwner.m_fDeleteRecords)
  3493. {
  3494. SPITFSNode spServerNode;
  3495. pNode->GetParent(&spServerNode);
  3496. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  3497. dwErr = pServer->DeleteWinsServer(dlgDeleteOwner.m_dwSelectedOwner);
  3498. if (dwErr == ERROR_SUCCESS)
  3499. {
  3500. // remove from list
  3501. for (int i = 0; i < m_pServerInfoArray->GetSize(); i++)
  3502. {
  3503. if (m_pServerInfoArray->GetAt(i).m_dwIp == dlgDeleteOwner.m_dwSelectedOwner)
  3504. {
  3505. m_pServerInfoArray->RemoveAt(i);
  3506. break;
  3507. }
  3508. }
  3509. }
  3510. }
  3511. else
  3512. {
  3513. dwErr = TombstoneAllRecords(dlgDeleteOwner.m_dwSelectedOwner, pNode);
  3514. }
  3515. END_WAIT_CURSOR
  3516. if (dwErr != ERROR_SUCCESS)
  3517. {
  3518. WinsMessageBox(dwErr);
  3519. }
  3520. // TODO trigger an update of whatever is in the active registrations result pane
  3521. }
  3522. return hr;
  3523. }
  3524. /*---------------------------------------------------------------------------
  3525. CActiveRegistrationsHandler::AppendScopeName(char* lpName,
  3526. char* lpScopeAppended)
  3527. Appends the scope name to the record name, when there isa scope name
  3528. attached to the record
  3529. ---------------------------------------------------------------------------*/
  3530. void
  3531. CActiveRegistrationsHandler::AppendScopeName(char* lpName, char* lpScopeAppended)
  3532. {
  3533. strcpy(lpScopeAppended, lpName);
  3534. char szTemp[MAX_PATH];
  3535. CString strScope = _T(".") + m_strStaticMappingScope;
  3536. // INTL$ Should the scope name be OEM as well?
  3537. WideToMBCS(strScope, szTemp, WINS_NAME_CODE_PAGE, WC_COMPOSITECHECK);
  3538. strcat(lpScopeAppended, szTemp);
  3539. }
  3540. /*---------------------------------------------------------------------------
  3541. CActiveRegistrationsHandler::TombstoneRecords()
  3542. Handles Tomsstoning of records
  3543. Author: v-shubk
  3544. ---------------------------------------------------------------------------*/
  3545. DWORD
  3546. CActiveRegistrationsHandler::TombstoneRecords
  3547. (
  3548. ITFSComponent * pComponent,
  3549. WinsRecord * pws
  3550. )
  3551. {
  3552. DWORD err = ERROR_SUCCESS;
  3553. // get the server node to retrive the handle for the WINS api
  3554. SPITFSNode spNode;
  3555. pComponent->GetSelectedNode(&spNode);
  3556. SPITFSNode spParentNode;
  3557. spNode->GetParent(&spParentNode);
  3558. CWinsServerHandler* pServer = GETHANDLER(CWinsServerHandler, spParentNode);
  3559. WINSINTF_VERS_NO_T MinVersNo;
  3560. WINSINTF_VERS_NO_T MaxVersNo;
  3561. MinVersNo = pws->liVersion;
  3562. MaxVersNo = MinVersNo;
  3563. // gotta get the owner of this record
  3564. WINSINTF_RECORD_ACTION_T recAction;
  3565. WINSINTF_RECORD_ACTION_T * precAction = &recAction;
  3566. ZeroMemory(&recAction, sizeof(recAction));
  3567. BYTE * pName = (BYTE*) WinsAllocMem(pws->dwNameLen + 1);
  3568. if (pName == NULL)
  3569. {
  3570. return ERROR_OUTOFMEMORY;
  3571. }
  3572. memset(pName, 0, pws->dwNameLen + 1);
  3573. memcpy(pName, pws->szRecordName, pws->dwNameLen);
  3574. recAction.pName = pName;
  3575. recAction.Cmd_e = WINSINTF_E_QUERY;
  3576. recAction.TypOfRec_e = HIWORD(pws->dwType);
  3577. recAction.fStatic = (pws->dwState & WINSDB_REC_STATIC) ? TRUE : FALSE;
  3578. recAction.pAdd = NULL;
  3579. recAction.NoOfAdds = 0;
  3580. recAction.NameLen = pws->dwNameLen;
  3581. // get the OwnerId for the mapping
  3582. // have to do this because the OwnerId in the raw data is bogus
  3583. #ifdef WINS_CLIENT_APIS
  3584. err = ::WinsRecordAction(pServer->GetBinding(), &precAction);
  3585. #else
  3586. err = ::WinsRecordAction(&precAction);
  3587. #endif WINS_CLIENT_APIS
  3588. WinsFreeMem(pName);
  3589. if (err != WINSINTF_SUCCESS )
  3590. {
  3591. return err;
  3592. }
  3593. WINSINTF_ADD_T WinsAdd;
  3594. WinsAdd.Len = 4;
  3595. WinsAdd.Type = 0;
  3596. //WinsAdd.IPAdd = m_dwArrayOwner[precAction->OwnerId];
  3597. WinsAdd.IPAdd = (*m_pServerInfoArray)[precAction->OwnerId].m_dwIp;
  3598. #ifdef WINS_CLIENT_APIS
  3599. err = ::WinsTombstoneDbRecs(pServer->GetBinding(),
  3600. &WinsAdd,
  3601. MinVersNo,
  3602. MaxVersNo);
  3603. #else
  3604. err = ::WinsTombstoneDbRecs(&WinsAdd,
  3605. MinVersNo,
  3606. MaxVersNo);
  3607. #endif
  3608. return err;
  3609. }
  3610. /*---------------------------------------------------------------------------
  3611. CActiveRegistrationsHandler::TombstoneAllRecords()
  3612. Tombstones all records owned by this server
  3613. Author: EricDav
  3614. ---------------------------------------------------------------------------*/
  3615. DWORD
  3616. CActiveRegistrationsHandler::TombstoneAllRecords(DWORD dwServerIpAddress, ITFSNode * pNode)
  3617. {
  3618. WINSINTF_VERS_NO_T MinVersNo;
  3619. WINSINTF_VERS_NO_T MaxVersNo;
  3620. WINSINTF_ADD_T WinsAdd;
  3621. SPITFSNode spParentNode;
  3622. pNode->GetParent(&spParentNode);
  3623. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spParentNode);
  3624. DWORD err;
  3625. CWinsResults winsResults;
  3626. err = winsResults.Update(pServer->GetBinding());
  3627. if (err != ERROR_SUCCESS)
  3628. return err;
  3629. MinVersNo.QuadPart = 0;
  3630. for (UINT i = 0; i < winsResults.NoOfOwners; i++)
  3631. {
  3632. if (winsResults.AddVersMaps[i].Add.IPAdd == dwServerIpAddress)
  3633. {
  3634. MaxVersNo.QuadPart = winsResults.AddVersMaps[i].VersNo.QuadPart;
  3635. break;
  3636. }
  3637. }
  3638. // build the IP address
  3639. WinsAdd.Len = 4;
  3640. WinsAdd.Type = 0;
  3641. WinsAdd.IPAdd = dwServerIpAddress;
  3642. #ifdef WINS_CLIENT_APIS
  3643. err = ::WinsTombstoneDbRecs(pServer->GetBinding(),
  3644. &WinsAdd,
  3645. MinVersNo,
  3646. MaxVersNo);
  3647. #else
  3648. err = ::WinsTombstoneDbRecs(&WinsAdd,
  3649. MinVersNo,
  3650. MaxVersNo);
  3651. #endif
  3652. return err;
  3653. }
  3654. /*---------------------------------------------------------------------------
  3655. CActiveRegistrationsHandler::UpdateRecord(ITFSComponent *pComponent,
  3656. WinsRecord *pws,
  3657. int nDelIndex)
  3658. Called to update the record on the result pane when a records has been
  3659. tombstoned
  3660. Author: v-shubk
  3661. ---------------------------------------------------------------------------*/
  3662. HRESULT
  3663. CActiveRegistrationsHandler::UpdateRecord(ITFSComponent *pComponent,
  3664. WinsRecord *pws,
  3665. int nDelIndex)
  3666. {
  3667. HRESULT hr = hrOK;
  3668. WINSINTF_RECORD_ACTION_T RecAction;
  3669. PWINSINTF_RECORD_ACTION_T pRecAction;
  3670. PWINSINTF_RECORD_ACTION_T pRecActionRet;
  3671. DWORD dwStatus = ERROR_SUCCESS;
  3672. int nLen;
  3673. BYTE bLast;
  3674. SPITFSNode spNode;
  3675. SPITFSNode spParentNode;
  3676. WinsRecord wsNew;
  3677. HROW hrowDel;
  3678. pComponent->GetSelectedNode(&spNode);
  3679. // get it's parent, which happens to be the server node
  3680. spNode->GetParent(&spParentNode);
  3681. // get the pointer to the server handler
  3682. CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spParentNode);
  3683. ZeroMemory(&RecAction, sizeof(RecAction));
  3684. // form the PWINSINTFrecord from the info in WinsRecord
  3685. //RecAction.TypOfRec_e = nType;
  3686. RecAction.Cmd_e = WINSINTF_E_QUERY;
  3687. RecAction.pAdd = NULL;
  3688. RecAction.pName = NULL;
  3689. RecAction.NoOfAdds = 0;
  3690. RecAction.NameLen = nLen = pws->dwNameLen;
  3691. bLast = LOBYTE(LOWORD(pws->dwType));
  3692. pRecAction = &RecAction;
  3693. RecAction.pName = (LPBYTE)::WinsAllocMem(nLen + 1);
  3694. if (RecAction.pName == NULL)
  3695. {
  3696. return ERROR_NOT_ENOUGH_MEMORY;
  3697. }
  3698. // copy the name
  3699. memset(pRecAction->pName, 0, nLen + 1);
  3700. (void)memcpy(pRecAction->pName, pws->szRecordName, nLen);
  3701. // now query for this particular record
  3702. pRecActionRet = QueryForName(spNode, pRecAction);
  3703. // if the function is successful, update the listbox
  3704. if (pRecActionRet != NULL)
  3705. {
  3706. // convert PWinsINTF record to WinsRecord so that it can be added to the local storage
  3707. WinsIntfToWinsRecord(pRecActionRet, wsNew);
  3708. if (pRecActionRet->OwnerId < (UINT) m_pServerInfoArray->GetSize())
  3709. wsNew.dwOwner = (*m_pServerInfoArray)[pRecActionRet->OwnerId].m_dwIp;
  3710. free(pRecActionRet->pName);
  3711. // delete this particular record and add it back again to the local storage
  3712. CORg(m_pCurrentDatabase->GetHRow(nDelIndex, &hrowDel));
  3713. CORg(m_pCurrentDatabase->DeleteRecord(hrowDel));
  3714. // add it to database
  3715. m_pCurrentDatabase->AddRecord(&wsNew);
  3716. }
  3717. Error:
  3718. if (RecAction.pName)
  3719. {
  3720. WinsFreeMem(RecAction.pName);
  3721. }
  3722. return hr;
  3723. }
  3724. /*---------------------------------------------------------------------------
  3725. CActiveRegistrationsHandler::RefreshResults(ITFSNode *pNode)
  3726. Refreshes the result pane of the active registrations node
  3727. ---------------------------------------------------------------------------*/
  3728. HRESULT
  3729. CActiveRegistrationsHandler::RefreshResults(ITFSNode *pNode)
  3730. {
  3731. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  3732. HRESULT hr = hrOK;
  3733. SPITFSNode spNode;
  3734. SPITFSNodeHandler spHandler;
  3735. ITFSQueryObject * pQuery = NULL;
  3736. SPITFSNode spServerNode;
  3737. DWORD dwIP;
  3738. CString strIP ;
  3739. CWinsServerHandler* pServer = NULL;
  3740. CString strMachineName;
  3741. int nCount, pos;
  3742. // if being loaded
  3743. if (m_spWinsDatabase)
  3744. {
  3745. CORg (m_spWinsDatabase->Stop());
  3746. DatabaseLoadingCleanup();
  3747. UpdateListboxCount(pNode);
  3748. }
  3749. pNode->GetParent(&spServerNode);
  3750. pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  3751. Lock();
  3752. strMachineName = _T("\\\\") + pServer->GetServerAddress();
  3753. dwIP = pServer->GetServerIP();
  3754. MakeIPAddress(dwIP, strIP);
  3755. if (!m_spWinsDatabase)
  3756. {
  3757. CORg(CreateWinsDatabase(strIP, strIP, &m_spWinsDatabase));
  3758. }
  3759. m_spWinsDatabase->SetApiInfo(
  3760. m_dlgLoadRecords.m_pageOwners.GetOwnerForApi(),
  3761. m_dlgLoadRecords.m_pageIpAddress.GetNameForApi(),
  3762. m_dlgLoadRecords.m_bEnableCache);
  3763. // start loading records
  3764. CORg (m_spWinsDatabase->Init());
  3765. UpdateCurrentView(pNode);
  3766. // update our internal state
  3767. m_winsdbState = WINSDB_LOADING;
  3768. // update the node's icon
  3769. OnChangeState(pNode);
  3770. // kick off the background thread to do the timer updates
  3771. pQuery = OnCreateQuery(pNode);
  3772. Assert(pQuery);
  3773. Verify(StartBackgroundThread(pNode,
  3774. m_spTFSCompData->GetHiddenWnd(),
  3775. pQuery));
  3776. pQuery->Release();
  3777. // fill in any record type filter information
  3778. nCount = (int)m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.GetSize();
  3779. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_TYPE);
  3780. for (pos = 0; pos < nCount; pos++)
  3781. {
  3782. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_TYPE,
  3783. m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].dwType,
  3784. m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].fShow,
  3785. NULL);
  3786. }
  3787. // fill in any owner filter information
  3788. nCount = (int)m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter.GetSize();
  3789. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_OWNER);
  3790. for (pos = 0; pos < nCount; pos++)
  3791. {
  3792. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_OWNER,
  3793. m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter[pos],
  3794. 0,
  3795. NULL);
  3796. }
  3797. // fill in any ip address filter information
  3798. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_IPADDR);
  3799. if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterIpAddr)
  3800. {
  3801. nCount = (int)m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs.GetSize();
  3802. for (pos = 0; pos < nCount; pos++)
  3803. {
  3804. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_IPADDR,
  3805. m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs[pos],
  3806. m_dlgLoadRecords.m_pageIpAddress.GetIPMaskForFilter(pos),
  3807. NULL);
  3808. }
  3809. }
  3810. // fill in any name filter information
  3811. m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_NAME);
  3812. if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterName)
  3813. {
  3814. m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_NAME,
  3815. m_dlgLoadRecords.m_pageIpAddress.m_bMatchCase,
  3816. 0,
  3817. m_dlgLoadRecords.m_pageIpAddress.m_strName);
  3818. }
  3819. // start loading records
  3820. CORg (m_spWinsDatabase->Start());
  3821. BEGIN_WAIT_CURSOR
  3822. // filter any records that may have been downloaded before we set the
  3823. // filter information (in the case when we had to reload the database).
  3824. // any records that come in after we set the
  3825. // filter info will be filtered correctly.
  3826. m_spWinsDatabase->FilterRecords(WINSDB_FILTER_BY_TYPE, 0,0);
  3827. END_WAIT_CURSOR
  3828. // do the initial update of the virutal listbox
  3829. OnHaveData(pNode, 0, QDATA_TIMER);
  3830. COM_PROTECT_ERROR_LABEL;
  3831. return hr;
  3832. }
  3833. /*---------------------------------------------------------------------------
  3834. CActiveRegistrationsHandler::GetRecordOwner()
  3835. Gets the owner IP Address for a given record
  3836. Author: EricDav
  3837. ---------------------------------------------------------------------------*/
  3838. BOOL
  3839. CActiveRegistrationsHandler::GetRecordOwner(ITFSNode * pNode, WinsRecord * pWinsRecord)
  3840. {
  3841. BOOL fSuccess = TRUE;
  3842. SPITFSNode spServerNode;
  3843. pNode->GetParent(&spServerNode);
  3844. CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
  3845. CConfiguration config = pServer->GetConfig();
  3846. if (!config.FSupportsOwnerId())
  3847. {
  3848. // query the server for correct info
  3849. WINSINTF_RECORD_ACTION_T RecAction;
  3850. ZeroMemory(&RecAction, sizeof(RecAction));
  3851. //
  3852. // Must have at least enough room for 256 character string,
  3853. // includes the scope name too
  3854. //
  3855. RecAction.pName = (LPBYTE)::WinsAllocMem(257);
  3856. if (RecAction.pName == NULL)
  3857. {
  3858. //return ERROR_NOT_ENOUGH_MEMORY;
  3859. Trace0("GetRecordOwner - WinsAllocMemFailed!!\n");
  3860. return FALSE;
  3861. }
  3862. // fill in the record action struct
  3863. ::memset(RecAction.pName, 0, 257);
  3864. ::memcpy((char *)RecAction.pName,
  3865. (LPCSTR) pWinsRecord->szRecordName,
  3866. pWinsRecord->dwNameLen);
  3867. RecAction.NameLen = strlen((char *) RecAction.pName);
  3868. // for name records of type 0x00 or records that somehow have a NULL in the name
  3869. // strlen will return an invalid string length. So, if the length < 16 then set
  3870. // the length to 16.
  3871. // name lengths with scopes will calculate correctly.
  3872. if (RecAction.NameLen < 0x10)
  3873. {
  3874. RecAction.NameLen = 0x10;
  3875. }
  3876. BOOL fStatic = (pWinsRecord->dwState & WINSDB_REC_STATIC) ? TRUE : FALSE;
  3877. // now query for the name
  3878. PWINSINTF_RECORD_ACTION_T pRecActionResult = QueryForName(pNode, &RecAction, fStatic);
  3879. if (pRecActionResult)
  3880. {
  3881. free(pRecActionResult->pName);
  3882. }
  3883. else
  3884. {
  3885. pWinsRecord->dwOwner = INVALID_OWNER_ID;
  3886. }
  3887. }
  3888. return fSuccess;
  3889. }
  3890. /*---------------------------------------------------------------------------
  3891. CActiveRegistrationsHandler::GetOwnerInfo()
  3892. Gets the owner info array
  3893. Author: EricDav
  3894. ---------------------------------------------------------------------------*/
  3895. void
  3896. CActiveRegistrationsHandler::GetOwnerInfo(CServerInfoArray & serverInfoArray)
  3897. {
  3898. serverInfoArray.RemoveAll();
  3899. serverInfoArray.Copy(*m_pServerInfoArray);
  3900. }
  3901. void CActiveRegistrationsHandler::SetLoadedOnce(ITFSNode * pNode)
  3902. {
  3903. if (m_fLoadedOnce)
  3904. return;
  3905. m_fLoadedOnce = TRUE;
  3906. // clear the result pane message
  3907. ClearMessage(pNode);
  3908. }