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

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