Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

815 lines
24 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. winscomp.cpp
  7. This file contains the derived implementations from CComponent
  8. and CComponentData for the WINS admin snapin.
  9. FILE HISTORY:
  10. */
  11. #include "stdafx.h"
  12. #include "winscomp.h"
  13. #include "root.h"
  14. #include "server.h"
  15. #include "vrfysrv.h"
  16. #include "status.h"
  17. #include <atlimpl.cpp>
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. #define HI HIDDEN
  24. #define EN ENABLED
  25. LARGE_INTEGER gliWinssnapVersion;
  26. UINT aColumns[WINSSNAP_NODETYPE_MAX][MAX_COLUMNS] =
  27. {
  28. {IDS_ROOT_NAME, IDS_STATUS, 0, 0, 0, 0, 0, 0,0}, // WINSSNAP_ROOT
  29. {IDS_WINSSERVER_NAME, IDS_DESCRIPTION, 0, 0, 0, 0, 0, 0,0}, // WINSSNAP_SERVER
  30. {IDS_ACTIVEREG_RECORD_NAME, IDS_ACTIVEREG_TYPE, IDS_ACTIVEREG_IPADDRESS, IDS_ACTIVEREG_ACTIVE, IDS_ACTIVEREG_STATIC,IDS_ACTREG_OWNER, IDS_ACTIVEREG_VERSION, IDS_ACTIVEREG_EXPIRATION,0}, // WINSSNAP_ACTIVE_REGISTRATIONS
  31. {IDS_REPLICATION_SERVERNAME,IDS_ACTIVEREG_IPADDRESS, IDS_ACTIVEREG_TYPE, 0, 0, 0, 0, 0,0}, // WINSSNAP_REPLICATION_PARTNERS
  32. {IDS_ROOT_NODENAME, IDS_ROOT_NODE_STATUS, IDS_LAST_UPDATE, 0, 0, 0, 0, 0,0}, // STATUS
  33. {0,0,0,0,0,0,0,0,0}
  34. };
  35. //
  36. // CODEWORK this should be in a resource, for example code on loading data resources see
  37. // D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
  38. // JonN 10/11/96
  39. //
  40. // StatusRemove
  41. int aColumnWidths[WINSSNAP_NODETYPE_MAX][MAX_COLUMNS] =
  42. {
  43. {250, 150, 50, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_ROOT
  44. {250, 250, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_SERVER
  45. {150, 120, 100, 75, 50, 100, 100, 150, AUTO_WIDTH}, // WINSSNAP_ACTIVE_REGISTRATIONS
  46. {100, 100, 100, 150, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_REPLICATION_PARTNERS
  47. {250, 100, 200, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_SERVER_STATUS
  48. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_SERVER_STATUS
  49. };
  50. // icon defines
  51. UINT g_uIconMap[ICON_IDX_MAX + 1][2] =
  52. {
  53. {IDI_ICON01, ICON_IDX_ACTREG_FOLDER_CLOSED},
  54. {IDI_ICON02, ICON_IDX_ACTREG_FOLDER_CLOSED_BUSY},
  55. {IDI_ICON03, ICON_IDX_ACTREG_FOLDER_OPEN},
  56. {IDI_ICON04, ICON_IDX_ACTREG_FOLDER_OPEN_BUSY},
  57. {IDI_ICON05, ICON_IDX_CLIENT},
  58. {IDI_ICON06, ICON_IDX_CLIENT_GROUP},
  59. {IDI_ICON07, ICON_IDX_PARTNER},
  60. {IDI_ICON08, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED},
  61. {IDI_ICON09, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED_BUSY},
  62. {IDI_ICON10, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED_LOST_CONNECTION},
  63. {IDI_ICON11, ICON_IDX_REP_PARTNERS_FOLDER_OPEN},
  64. {IDI_ICON12, ICON_IDX_REP_PARTNERS_FOLDER_OPEN_BUSY},
  65. {IDI_ICON13, ICON_IDX_REP_PARTNERS_FOLDER_OPEN_LOST_CONNECTION},
  66. {IDI_ICON14, ICON_IDX_SERVER},
  67. {IDI_ICON15, ICON_IDX_SERVER_BUSY},
  68. {IDI_ICON16, ICON_IDX_SERVER_CONNECTED},
  69. {IDI_ICON17, ICON_IDX_SERVER_LOST_CONNECTION},
  70. {IDI_ICON18, ICON_IDX_SERVER_NO_ACCESS},
  71. {IDI_WINS_SNAPIN, ICON_IDX_WINS_PRODUCT},
  72. {0, 0}
  73. };
  74. // help mapper for dialogs and property pages
  75. struct ContextHelpMap
  76. {
  77. UINT uID;
  78. const DWORD * pdwMap;
  79. };
  80. ContextHelpMap g_uContextHelp[WINSSNAP_NUM_HELP_MAPS] =
  81. {
  82. {IDD_ACTREG_FIND_RECORD, g_aHelpIDs_IDD_ACTREG_FIND_RECORD},
  83. {IDD_CHECK_REG_NAMES, g_aHelpIDs_IDD_CHECK_REG_NAMES},
  84. {IDD_DELTOMB_RECORD, g_aHelpIDs_IDD_DELTOMB_RECORD},
  85. {IDD_DYN_PROPERTIES, g_aHelpIDs_IDD_DYN_PROPERTIES},
  86. {IDD_FILTER_SELECT, g_aHelpIDs_IDD_FILTER_SELECT},
  87. {IDD_GETIPADDRESS, g_aHelpIDs_IDD_GETIPADDRESS},
  88. {IDD_GETNETBIOSNAME, g_aHelpIDs_IDD_GETNETBIOSNAME},
  89. {IDD_IPADDRESS, g_aHelpIDs_IDD_IPADDRESS},
  90. {IDD_NAME_TYPE, g_aHelpIDs_IDD_NAME_TYPE},
  91. {IDD_OWNER_DELETE, g_aHelpIDs_IDD_OWNER_DELETE},
  92. {IDD_OWNER_FILTER, g_aHelpIDs_IDD_OWNER_FILTER},
  93. {IDD_FILTER_IPADDR, g_aHelpIDs_IDD_FILTER_IPADDR},
  94. {IDD_PULL_TRIGGER, NULL},
  95. {IDD_REP_NODE_ADVANCED, g_aHelpIDs_IDD_REP_NODE_ADVANCED},
  96. {IDD_REP_NODE_PUSH, g_aHelpIDs_IDD_REP_NODE_PUSH},
  97. {IDD_REP_NODE_PULL, g_aHelpIDs_IDD_REP_NODE_PULL},
  98. {IDD_REP_NODE_GENERAL, g_aHelpIDs_IDD_REP_NODE_GENERAL},
  99. {IDD_REP_PROP_ADVANCED, g_aHelpIDs_IDD_REP_PROP_ADVANCED},
  100. {IDD_REP_PROP_GENERAL, g_aHelpIDs_IDD_REP_PROP_GENERAL},
  101. {IDD_SEND_PUSH_TRIGGER, g_aHelpIDs_IDD_SEND_PUSH_TRIGGER},
  102. {IDD_SERVER_PROP_ADVANCED, g_aHelpIDs_IDD_SERVER_PROP_ADVANCED},
  103. {IDD_SERVER_PROP_DBRECORD, g_aHelpIDs_IDD_SERVER_PROP_DBRECORD},
  104. {IDD_SERVER_PROP_DBVERIFICATION, g_aHelpIDs_IDD_SERVER_PROP_DBVERIFICATION},
  105. {IDD_SERVER_PROP_GEN, g_aHelpIDs_IDD_SERVER_PROP_GEN},
  106. {IDD_SNAPIN_PP_GENERAL, g_aHelpIDs_IDD_SNAPIN_PP_GENERAL},
  107. {IDD_STATIC_MAPPING_PROPERTIES, g_aHelpIDs_IDD_STATIC_MAPPING_PROPERTIES},
  108. {IDD_STATIC_MAPPING_WIZARD, g_aHelpIDs_IDD_STATIC_MAPPING_WIZARD},
  109. {IDD_STATS_NARROW, NULL},
  110. {IDD_STATUS_NODE_PROPERTIES, g_aHelpIDs_IDD_STATUS_NODE_PROPERTIES},
  111. {IDD_VERIFY_WINS, NULL},
  112. {IDD_VERSION_CONSIS, g_aHelpIDs_IDD_VERSION_CONSIS},
  113. };
  114. CWinsContextHelpMap g_winsContextHelpMap;
  115. DWORD * WinsGetHelpMap(UINT uID)
  116. {
  117. DWORD * pdwMap = NULL;
  118. g_winsContextHelpMap.Lookup(uID, pdwMap);
  119. return pdwMap;
  120. }
  121. CString aMenuButtonText[3][2];
  122. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  123. /////////////////////////////////////////////////////////////////////////////
  124. // CWinsComponent implementation
  125. /*---------------------------------------------------------------------------
  126. Class CWinsComponent implementation
  127. ---------------------------------------------------------------------------*/
  128. CWinsComponent::CWinsComponent()
  129. {
  130. }
  131. CWinsComponent::~CWinsComponent()
  132. {
  133. }
  134. STDMETHODIMP CWinsComponent::InitializeBitmaps(MMC_COOKIE cookie)
  135. {
  136. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  137. ASSERT(m_spImageList != NULL);
  138. HICON hIcon;
  139. for (int i = 0; i < ICON_IDX_MAX; i++)
  140. {
  141. hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
  142. if (hIcon)
  143. {
  144. // call mmc
  145. m_spImageList->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1]);
  146. }
  147. }
  148. return S_OK;
  149. }
  150. /*!--------------------------------------------------------------------------
  151. CWinsComponent::QueryDataObject
  152. Implementation of IComponent::QueryDataObject. We need this for
  153. virtual listbox support. MMC calls us back normally with the cookie
  154. we handed it... In the case of the VLB, it hands us the index of
  155. the item. So, we need to do some extra checking...
  156. Author: EricDav
  157. ---------------------------------------------------------------------------*/
  158. STDMETHODIMP
  159. CWinsComponent::QueryDataObject
  160. (
  161. MMC_COOKIE cookie,
  162. DATA_OBJECT_TYPES type,
  163. LPDATAOBJECT* ppDataObject
  164. )
  165. {
  166. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  167. HRESULT hr = hrOK;
  168. SPITFSNode spSelectedNode;
  169. SPITFSNode spRootNode;
  170. SPITFSResultHandler spResultHandler;
  171. long lViewOptions = 0;
  172. LPOLESTR pViewType = NULL;
  173. CDataObject * pDataObject;
  174. COM_PROTECT_TRY
  175. {
  176. // check to see what kind of result view type the selected node has
  177. CORg (GetSelectedNode(&spSelectedNode));
  178. CORg (spSelectedNode->GetResultHandler(&spResultHandler));
  179. CORg (spResultHandler->OnGetResultViewType(this, spSelectedNode->GetData(TFS_DATA_COOKIE), &pViewType, &lViewOptions));
  180. if ( (lViewOptions & MMC_VIEW_OPTIONS_OWNERDATALIST) ||
  181. (cookie == MMC_MULTI_SELECT_COOKIE) )
  182. {
  183. if (cookie == MMC_MULTI_SELECT_COOKIE)
  184. {
  185. // this is a special case for multiple select. We need to build a list
  186. // of GUIDs and the code to do this is in the handler...
  187. spResultHandler->OnCreateDataObject(this, cookie, type, ppDataObject);
  188. }
  189. else
  190. {
  191. // this node has a virtual listbox for the result pane. Gerenate
  192. // a special data object using the selected node as the cookie
  193. Assert(m_spComponentData != NULL);
  194. CORg (m_spComponentData->QueryDataObject(reinterpret_cast<LONG_PTR>((ITFSNode *) spSelectedNode), type, ppDataObject));
  195. }
  196. pDataObject = reinterpret_cast<CDataObject *>(*ppDataObject);
  197. pDataObject->SetVirtualIndex((int) cookie);
  198. }
  199. else
  200. if (cookie == MMC_WINDOW_COOKIE)
  201. {
  202. // this cookie needs the text for the static root node, so build the DO with
  203. // the root node cookie
  204. m_spNodeMgr->GetRootNode(&spRootNode);
  205. CORg (m_spComponentData->QueryDataObject((MMC_COOKIE) spRootNode->GetData(TFS_DATA_COOKIE), type, ppDataObject));
  206. }
  207. else
  208. {
  209. // just forward this to the component data
  210. Assert(m_spComponentData != NULL);
  211. CORg (m_spComponentData->QueryDataObject(cookie, type, ppDataObject));
  212. }
  213. COM_PROTECT_ERROR_LABEL;
  214. }
  215. COM_PROTECT_CATCH
  216. return hr;
  217. }
  218. /*!--------------------------------------------------------------------------
  219. CWinsComponent::OnSnapinHelp
  220. -
  221. Author: v-shubk
  222. ---------------------------------------------------------------------------*/
  223. STDMETHODIMP
  224. CWinsComponent::OnSnapinHelp
  225. (
  226. LPDATAOBJECT pDataObject,
  227. LPARAM arg,
  228. LPARAM param
  229. )
  230. {
  231. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  232. HRESULT hr = hrOK;
  233. HtmlHelpA(NULL, "WinsSnap.chm", HH_DISPLAY_TOPIC, 0);
  234. return hr;
  235. }
  236. /*!--------------------------------------------------------------------------
  237. CWinsComponent::CompareObjects
  238. Implementation of IComponent::CompareObjects
  239. MMC calls this to compare two objects
  240. We override this for the virtual listbox case. With a virtual listbox,
  241. the cookies are the same, but the index in the internal structs
  242. indicate which item the dataobject refers to. So, we need to look
  243. at the indicies instead of just the cookies.
  244. Author:
  245. ---------------------------------------------------------------------------*/
  246. STDMETHODIMP
  247. CWinsComponent::CompareObjects
  248. (
  249. LPDATAOBJECT lpDataObjectA,
  250. LPDATAOBJECT lpDataObjectB
  251. )
  252. {
  253. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  254. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  255. return E_POINTER;
  256. // Make sure both data object are mine
  257. SPINTERNAL spA;
  258. SPINTERNAL spB;
  259. HRESULT hr = S_FALSE;
  260. COM_PROTECT_TRY
  261. {
  262. spA = ExtractInternalFormat(lpDataObjectA);
  263. spB = ExtractInternalFormat(lpDataObjectB);
  264. if (spA != NULL && spB != NULL)
  265. {
  266. if (spA->HasVirtualIndex() && spB->HasVirtualIndex())
  267. {
  268. hr = (spA->GetVirtualIndex() == spB->GetVirtualIndex()) ? S_OK : S_FALSE;
  269. }
  270. else
  271. {
  272. hr = (spA->m_cookie == spB->m_cookie) ? S_OK : S_FALSE;
  273. }
  274. }
  275. }
  276. COM_PROTECT_CATCH
  277. return hr;
  278. }
  279. /*---------------------------------------------------------------------------
  280. Class CWinsComponentData implementation
  281. ---------------------------------------------------------------------------*/
  282. CWinsComponentData::CWinsComponentData()
  283. {
  284. // initialize our global help map
  285. for (int i = 0; i < WINSSNAP_NUM_HELP_MAPS; i++)
  286. {
  287. g_winsContextHelpMap.SetAt(g_uContextHelp[i].uID, (LPDWORD) g_uContextHelp[i].pdwMap);
  288. }
  289. }
  290. /*!--------------------------------------------------------------------------
  291. CWinsComponentData::OnInitialize
  292. -
  293. Author: EricDav, KennT
  294. ---------------------------------------------------------------------------*/
  295. STDMETHODIMP CWinsComponentData::OnInitialize(LPIMAGELIST pScopeImage)
  296. {
  297. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  298. HICON hIcon;
  299. for (int i = 0; i < ICON_IDX_MAX; i++)
  300. {
  301. hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
  302. if (hIcon)
  303. {
  304. // call mmc
  305. VERIFY(SUCCEEDED(pScopeImage->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
  306. }
  307. }
  308. return hrOK;
  309. }
  310. /*!--------------------------------------------------------------------------
  311. CWinsComponentData::OnDestroy
  312. -
  313. Author: EricDav, KennT
  314. ---------------------------------------------------------------------------*/
  315. STDMETHODIMP CWinsComponentData::OnDestroy()
  316. {
  317. m_spNodeMgr.Release();
  318. return hrOK;
  319. }
  320. /*!--------------------------------------------------------------------------
  321. CWinsComponentData::OnInitializeNodeMgr
  322. -
  323. Author: KennT
  324. ---------------------------------------------------------------------------*/
  325. STDMETHODIMP
  326. CWinsComponentData::OnInitializeNodeMgr
  327. (
  328. ITFSComponentData * pTFSCompData,
  329. ITFSNodeMgr * pNodeMgr
  330. )
  331. {
  332. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  333. // For now create a new node handler for each new node,
  334. // this is rather bogus as it can get expensive. We can
  335. // consider creating only a single node handler for each
  336. // node type.
  337. CWinsRootHandler * pHandler = NULL;
  338. SPITFSNodeHandler spHandler;
  339. SPITFSNode spNode;
  340. HRESULT hr = hrOK;
  341. try
  342. {
  343. pHandler = new CWinsRootHandler(pTFSCompData);
  344. // Do this so that it will get released correctly
  345. spHandler = pHandler;
  346. }
  347. catch(...)
  348. {
  349. hr = E_OUTOFMEMORY;
  350. }
  351. CORg( hr );
  352. // Create the root node for this sick puppy
  353. CORg( CreateContainerTFSNode(&spNode,
  354. &GUID_WinsGenericNodeType,
  355. pHandler,
  356. pHandler, /* result handler */
  357. pNodeMgr) );
  358. // Need to initialize the data for the root node
  359. pHandler->InitializeNode(spNode);
  360. CORg( pNodeMgr->SetRootNode(spNode) );
  361. m_spRootNode.Set(spNode);
  362. pTFSCompData->SetHTMLHelpFileName(_T("winssnap.chm"));
  363. Error:
  364. return hr;
  365. }
  366. /*!--------------------------------------------------------------------------
  367. CWinsComponentData::OnCreateComponent
  368. -
  369. Author: EricDav, KennT
  370. ---------------------------------------------------------------------------*/
  371. STDMETHODIMP
  372. CWinsComponentData::OnCreateComponent
  373. (
  374. LPCOMPONENT *ppComponent
  375. )
  376. {
  377. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  378. ASSERT(ppComponent != NULL);
  379. HRESULT hr = hrOK;
  380. CWinsComponent * pComp = NULL;
  381. try
  382. {
  383. pComp = new CWinsComponent;
  384. }
  385. catch(...)
  386. {
  387. hr = E_OUTOFMEMORY;
  388. }
  389. if (FHrSucceeded(hr))
  390. {
  391. pComp->Construct(m_spNodeMgr,
  392. static_cast<IComponentData *>(this),
  393. m_spTFSComponentData);
  394. *ppComponent = static_cast<IComponent *>(pComp);
  395. }
  396. return hr;
  397. }
  398. /*!--------------------------------------------------------------------------
  399. CWinsComponentData::GetCoClassID
  400. -
  401. Author: KennT
  402. ---------------------------------------------------------------------------*/
  403. STDMETHODIMP_(const CLSID *)
  404. CWinsComponentData::GetCoClassID()
  405. {
  406. return &CLSID_WinsSnapin;
  407. }
  408. /*!--------------------------------------------------------------------------
  409. CSfmComponentData::OnCreateDataObject
  410. -
  411. Author: KennT
  412. ---------------------------------------------------------------------------*/
  413. STDMETHODIMP
  414. CWinsComponentData::OnCreateDataObject
  415. (
  416. MMC_COOKIE cookie,
  417. DATA_OBJECT_TYPES type,
  418. IDataObject ** ppDataObject
  419. )
  420. {
  421. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  422. Assert(ppDataObject != NULL);
  423. CDataObject * pObject = NULL;
  424. SPIDataObject spDataObject;
  425. pObject = new CDataObject;
  426. spDataObject = pObject; // do this so that it gets released correctly
  427. Assert(pObject != NULL);
  428. // Save cookie and type for delayed rendering
  429. pObject->SetType(type);
  430. pObject->SetCookie(cookie);
  431. // Store the coclass with the data object
  432. pObject->SetClsid(*GetCoClassID());
  433. pObject->SetTFSComponentData(m_spTFSComponentData);
  434. return pObject->QueryInterface(IID_IDataObject,
  435. reinterpret_cast<void**>(ppDataObject));
  436. }
  437. ///////////////////////////////////////////////////////////////////////////////
  438. //// IPersistStream interface members
  439. STDMETHODIMP
  440. CWinsComponentData::GetClassID
  441. (
  442. CLSID *pClassID
  443. )
  444. {
  445. ASSERT(pClassID != NULL);
  446. // Copy the CLSID for this snapin
  447. *pClassID = CLSID_WinsSnapin;
  448. return hrOK;
  449. }
  450. STDMETHODIMP
  451. CWinsComponentData::IsDirty()
  452. {
  453. return m_spRootNode->GetData(TFS_DATA_DIRTY) ? hrOK : hrFalse;
  454. }
  455. STDMETHODIMP
  456. CWinsComponentData::Load
  457. (
  458. IStream *pStm
  459. )
  460. {
  461. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  462. HRESULT hr = S_OK;
  463. LARGE_INTEGER liSavedVersion;
  464. CString str;
  465. ASSERT(pStm);
  466. CDWordArray dwArrayIp;
  467. CDWordArray dwArrayFlags;
  468. CDWordArray dwArrayRefreshInterval;
  469. CDWordArray dwArrayColumnInfo;
  470. DWORD dwUpdateInterval;
  471. DWORD dwSnapinFlags;
  472. CStringArray strArrayName;
  473. ULONG nNumReturned = 0;
  474. DWORD dwFileVersion;
  475. CWinsRootHandler * pRootHandler;
  476. SPITFSNodeEnum spNodeEnum;
  477. SPITFSNode spCurrentNode;
  478. HCURSOR hOldCursor;
  479. HCURSOR hNewCursor;
  480. int i;
  481. // set the mode for this stream
  482. XferStream xferStream(pStm, XferStream::MODE_READ);
  483. // read the version of the file format
  484. CORg(xferStream.XferDWORD(WINSSTRM_TAG_VERSION, &dwFileVersion));
  485. // Read the version # of the admin tool
  486. CORg(xferStream.XferLARGEINTEGER(WINSSTRM_TAG_VERSIONADMIN, &liSavedVersion));
  487. if (liSavedVersion.QuadPart < gliWinssnapVersion.QuadPart)
  488. {
  489. // File is an older version. Warn the user and then don't
  490. // load anything else
  491. Assert(FALSE);
  492. }
  493. // Read the root node name
  494. CORg(xferStream.XferCString(WINSSTRM_TAB_SNAPIN_NAME, &str));
  495. Assert(m_spRootNode);
  496. pRootHandler = GETHANDLER(CWinsRootHandler, m_spRootNode);
  497. pRootHandler->SetDisplayName(str);
  498. // read the root node info
  499. CORg(xferStream.XferDWORD(WINSSTRM_TAG_SNAPIN_FLAGS, &dwSnapinFlags));
  500. pRootHandler->m_dwFlags = dwSnapinFlags;
  501. pRootHandler->m_fValidate = (dwSnapinFlags & FLAG_VALIDATE_CACHE) ? TRUE : FALSE;
  502. // read from the stream
  503. CORg(xferStream.XferDWORD(WINSSTRM_TAG_UPDATE_INTERVAL, &dwUpdateInterval));
  504. pRootHandler->SetUpdateInterval(dwUpdateInterval);
  505. // now read all of the server information
  506. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_IP, &dwArrayIp));
  507. CORg(xferStream.XferCStringArray(WINSSTRM_TAG_SERVER_NAME, &strArrayName));
  508. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_FLAGS, &dwArrayFlags));
  509. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_REFRESHINTERVAL, &dwArrayRefreshInterval));
  510. hOldCursor = NULL;
  511. hNewCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
  512. if (hNewCursor)
  513. hOldCursor = SetCursor(hNewCursor);
  514. // now create the servers based on the information
  515. for (i = 0; i < dwArrayIp.GetSize(); i++)
  516. {
  517. //
  518. // now create the server object
  519. //
  520. pRootHandler->AddServer((LPCWSTR) strArrayName[i],
  521. FALSE,
  522. dwArrayIp[i],
  523. FALSE,
  524. dwArrayFlags[i],
  525. dwArrayRefreshInterval[i]
  526. );
  527. }
  528. pRootHandler->DismissVerifyDialog();
  529. // load the column information
  530. for (i = 0; i < NUM_SCOPE_ITEMS; i++)
  531. {
  532. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
  533. for (int j = 0; j < MAX_COLUMNS; j++)
  534. {
  535. aColumnWidths[i][j] = dwArrayColumnInfo[j];
  536. }
  537. }
  538. if (hOldCursor)
  539. SetCursor(hOldCursor);
  540. Error:
  541. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  542. }
  543. STDMETHODIMP
  544. CWinsComponentData::Save
  545. (
  546. IStream *pStm,
  547. BOOL fClearDirty
  548. )
  549. {
  550. HRESULT hr = hrOK;
  551. CDWordArray dwArrayIp;
  552. CStringArray strArrayName;
  553. CDWordArray dwArrayFlags;
  554. CDWordArray dwArrayRefreshInterval;
  555. CDWordArray dwArrayColumnInfo;
  556. DWORD dwUpdateInterval;
  557. DWORD dwSnapinFlags;
  558. DWORD dwFileVersion = WINSSNAP_FILE_VERSION;
  559. CString str;
  560. CWinsRootHandler * pRootHandler;
  561. int nNumServers = 0, nVisibleCount = 0;
  562. SPITFSNodeEnum spNodeEnum;
  563. SPITFSNode spCurrentNode;
  564. ULONG nNumReturned = 0;
  565. int nCount = 0;
  566. const GUID * pGuid;
  567. CWinsServerHandler *pServer;
  568. int i;
  569. ASSERT(pStm);
  570. // set the mode for this stream
  571. XferStream xferStream(pStm, XferStream::MODE_WRITE);
  572. // Write the version # of the file format
  573. CORg(xferStream.XferDWORD(WINSSTRM_TAG_VERSION, &dwFileVersion));
  574. // Write the version # of the admin tool
  575. CORg(xferStream.XferLARGEINTEGER(WINSSTRM_TAG_VERSIONADMIN, &gliWinssnapVersion));
  576. // write the root node name
  577. Assert(m_spRootNode);
  578. pRootHandler = GETHANDLER(CWinsRootHandler, m_spRootNode);
  579. str = pRootHandler->GetDisplayName();
  580. CORg(xferStream.XferCString(WINSSTRM_TAB_SNAPIN_NAME, &str));
  581. //
  582. // Build our array of servers
  583. //
  584. hr = m_spRootNode->GetChildCount(&nVisibleCount, &nNumServers);
  585. dwArrayColumnInfo.SetSize(MAX_COLUMNS);
  586. // save the root node info
  587. dwSnapinFlags = pRootHandler->m_dwFlags;
  588. CORg(xferStream.XferDWORD(WINSSTRM_TAG_SNAPIN_FLAGS, &dwSnapinFlags));
  589. dwUpdateInterval = pRootHandler->GetUpdateInterval();
  590. CORg(xferStream.XferDWORD(WINSSTRM_TAG_UPDATE_INTERVAL, &dwUpdateInterval));
  591. //
  592. // loop and save off all the server's attributes
  593. //
  594. m_spRootNode->GetEnum(&spNodeEnum);
  595. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  596. while (nNumReturned)
  597. {
  598. pGuid = spCurrentNode->GetNodeType();
  599. if (*pGuid == GUID_WinsServerStatusNodeType)
  600. {
  601. // go to the next node
  602. spCurrentNode.Release();
  603. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  604. //nCount++;
  605. continue;
  606. }
  607. pServer = GETHANDLER(CWinsServerHandler, spCurrentNode);
  608. // put the information in our array
  609. strArrayName.Add(pServer->GetServerAddress());
  610. dwArrayIp.Add(pServer->GetServerIP());
  611. dwArrayFlags.Add(pServer->m_dwFlags);
  612. dwArrayRefreshInterval.Add(pServer->m_dwRefreshInterval);
  613. // go to the next node
  614. spCurrentNode.Release();
  615. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  616. nCount++;
  617. }
  618. // now write out all of the server information
  619. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_IP, &dwArrayIp));
  620. CORg(xferStream.XferCStringArray(WINSSTRM_TAG_SERVER_NAME, &strArrayName));
  621. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_FLAGS, &dwArrayFlags));
  622. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_REFRESHINTERVAL, &dwArrayRefreshInterval));
  623. // save the column information
  624. for (i = 0; i < NUM_SCOPE_ITEMS; i++)
  625. {
  626. for (int j = 0; j < MAX_COLUMNS; j++)
  627. {
  628. dwArrayColumnInfo[j] = aColumnWidths[i][j];
  629. }
  630. CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
  631. }
  632. if (fClearDirty)
  633. {
  634. m_spRootNode->SetData(TFS_DATA_DIRTY, FALSE);
  635. }
  636. Error:
  637. return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
  638. }
  639. STDMETHODIMP
  640. CWinsComponentData::GetSizeMax
  641. (
  642. ULARGE_INTEGER *pcbSize
  643. )
  644. {
  645. ASSERT(pcbSize);
  646. // Set the size of the string to be saved
  647. ULISet32(*pcbSize, 10000);
  648. return S_OK;
  649. }
  650. STDMETHODIMP
  651. CWinsComponentData::InitNew()
  652. {
  653. return hrOK;
  654. }
  655. HRESULT
  656. CWinsComponentData::FinalConstruct()
  657. {
  658. HRESULT hr = hrOK;
  659. hr = CComponentData::FinalConstruct();
  660. if (FHrSucceeded(hr))
  661. {
  662. m_spTFSComponentData->GetNodeMgr(&m_spNodeMgr);
  663. }
  664. return hr;
  665. }
  666. void
  667. CWinsComponentData::FinalRelease()
  668. {
  669. CComponentData::FinalRelease();
  670. }