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.

1509 lines
25 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. lbcnfg.cxx
  5. Abstract:
  6. Classes to handle IIS load balancing configuration
  7. Author:
  8. Philippe Choquier (phillich)
  9. --*/
  10. #include <windows.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <mbstring.h>
  14. #include <winsock2.h>
  15. #include "lbxbf.hxx"
  16. #include "lbcnfg.hxx"
  17. #if defined(_NOISY_DEBUG)
  18. #define DEBUG_BUFFER char achE[128]
  19. #define DBG_PRINTF(a) wsprintf a; OutputDebugString( achE )
  20. #define DBG_PUTS(a) OutputDebugString(a)
  21. #else
  22. #define DEBUG_BUFFER
  23. #define DBG_PRINTF(a)
  24. #define DBG_PUTS(a)
  25. #endif
  26. CIPMap::CIPMap(
  27. )
  28. /*++
  29. Routine Description:
  30. CIPMap constructor
  31. Arguments:
  32. none
  33. Return Value:
  34. nothing
  35. --*/
  36. {
  37. }
  38. CIPMap::~CIPMap(
  39. )
  40. /*++
  41. Routine Description:
  42. CIPMap destructor
  43. Arguments:
  44. none
  45. Return Value:
  46. nothing
  47. --*/
  48. {
  49. Reset();
  50. }
  51. VOID
  52. CIPMap::Reset(
  53. )
  54. /*++
  55. Routine Description:
  56. Reset a CIPMap to empty content
  57. Arguments:
  58. none
  59. Return Value:
  60. nothing
  61. --*/
  62. {
  63. UINT iComp;
  64. for ( iComp = 0 ;
  65. iComp < m_Servers.GetNbPtr() ;
  66. ++iComp )
  67. {
  68. delete (CComputerBalanceCnfg*)m_Servers.GetPtr( iComp );
  69. }
  70. m_Servers.Reset();
  71. m_IpPublic.Reset();
  72. m_Sticky.Reset();
  73. m_Attr.Reset();
  74. }
  75. BOOL
  76. CIPMap::Serialize(
  77. CStoreXBF* pX
  78. )
  79. /*++
  80. Routine Description:
  81. serialize a CIPMap to buffer
  82. Arguments:
  83. buffer where to serialize
  84. Return Value:
  85. TRUE if success, otherwise FALSE
  86. --*/
  87. {
  88. UINT iComp;
  89. if ( !::Serialize( pX, (DWORD)IPLIST_VERSION ) )
  90. {
  91. return FALSE;
  92. }
  93. if ( !::Serialize( pX, (DWORD)m_Servers.GetNbPtr() ) )
  94. {
  95. return FALSE;
  96. }
  97. if ( !::Serialize( pX, (DWORD)m_IpPublic.GetNbEntry() ) )
  98. {
  99. return FALSE;
  100. }
  101. for ( iComp = 0 ;
  102. iComp < m_Servers.GetNbPtr() ;
  103. ++iComp )
  104. {
  105. if ( !((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->Serialize( pX ) )
  106. {
  107. return FALSE;
  108. }
  109. }
  110. if ( !m_IpPublic.Serialize( pX ) ||
  111. !m_Name.Serialize( pX ) ||
  112. !m_Sticky.Serialize( pX ) ||
  113. !m_Attr.Serialize( pX ) )
  114. {
  115. return FALSE;
  116. }
  117. return TRUE;
  118. }
  119. BOOL
  120. CIPMap::Unserialize(
  121. CStoreXBF* pX
  122. )
  123. /*++
  124. Routine Description:
  125. Unserialize a CIPMap
  126. Arguments:
  127. pX - ptr to buffer
  128. Return Value:
  129. TRUE if success, otherwise FALSE
  130. --*/
  131. {
  132. LPBYTE pb = pX->GetBuff();
  133. DWORD dw = pX->GetUsed();
  134. return Unserialize( &pb, &dw );
  135. }
  136. BOOL
  137. CIPMap::Unserialize(
  138. LPBYTE* ppb,
  139. LPDWORD pc
  140. )
  141. /*++
  142. Routine Description:
  143. Unserialize IP Map
  144. Arguments:
  145. ppb - ptr to addr of buffer to unserialize from
  146. pc - ptr to count of bytes in buffer
  147. Return Value:
  148. TRUE if success, otherwise FALSE
  149. --*/
  150. {
  151. DWORD dwComp;
  152. UINT iComp;
  153. DWORD dwPublicIp;
  154. UINT iPublicIp;
  155. CComputerBalanceCnfg* pComp;
  156. DWORD dwVersion;
  157. DEBUG_BUFFER;
  158. Reset();
  159. if ( !::Unserialize( ppb, pc, &dwVersion ) )
  160. {
  161. return FALSE;
  162. }
  163. if ( !::Unserialize( ppb, pc, &dwComp ) ||
  164. !::Unserialize( ppb, pc, &dwPublicIp ) )
  165. {
  166. DBG_PRINTF(( achE, "CIPMap::Unserialize error 1, pb=%08x c=%d\n", *ppb, *pc));
  167. return FALSE;
  168. }
  169. for ( iComp = 0 ;
  170. iComp < dwComp ;
  171. ++iComp )
  172. {
  173. if ( !(pComp = new CComputerBalanceCnfg) ||
  174. m_Servers.AddPtr( pComp ) == INDEX_ERROR ||
  175. !pComp->Unserialize( ppb, pc, dwPublicIp ) )
  176. {
  177. DBG_PUTS("CIPMap::Unserialize error 2\n" );
  178. return FALSE;
  179. }
  180. }
  181. if ( !m_IpPublic.Unserialize( ppb, pc, dwPublicIp ) ||
  182. !m_Name.Unserialize( ppb, pc, dwPublicIp ) ||
  183. !m_Sticky.Unserialize( ppb, pc, dwPublicIp ) ||
  184. !m_Attr.Unserialize( ppb, pc, dwPublicIp ) )
  185. {
  186. DBG_PUTS("CIPMap::Unserialize error 3\n" );
  187. return FALSE;
  188. }
  189. return TRUE;
  190. }
  191. BOOL
  192. LoadBlobFromReg(
  193. HKEY hKey,
  194. LPSTR pszRegKey,
  195. LPSTR pszRegValue,
  196. CStoreXBF* pX
  197. )
  198. /*++
  199. Routine Description:
  200. Load a buffer from registry
  201. Arguments:
  202. hKey - registry handle where to open key to read value
  203. pszRegKey - key where to read value
  204. pszRegValue - value name
  205. pX - ptr to buffer
  206. Return Value:
  207. TRUE if success, otherwise FALSE
  208. --*/
  209. {
  210. BOOL fSt = FALSE;
  211. HKEY hK;
  212. DWORD dwNeed;
  213. DWORD dwType;
  214. DWORD dwStatus;
  215. CHAR achE[128];
  216. if ( (dwStatus = RegOpenKeyEx( hKey,
  217. pszRegKey,
  218. 0,
  219. KEY_READ,
  220. &hK )) == ERROR_SUCCESS )
  221. {
  222. dwNeed = 0;
  223. if ( (dwStatus = RegQueryValueEx( hK,
  224. pszRegValue,
  225. 0,
  226. &dwType,
  227. NULL,
  228. &dwNeed )) == ERROR_SUCCESS &&
  229. dwType == REG_BINARY &&
  230. pX->Need( dwNeed ) &&
  231. (dwStatus = RegQueryValueEx( hK,
  232. pszRegValue,
  233. 0,
  234. &dwType,
  235. pX->GetBuff(),
  236. &dwNeed )) == ERROR_SUCCESS )
  237. {
  238. pX->SetUsed( dwNeed );
  239. fSt = TRUE;
  240. }
  241. RegCloseKey( hK );
  242. }
  243. if ( !fSt )
  244. {
  245. SetLastError( dwStatus );
  246. DBG_PUTS( "Error LoadBlobFromReg\n" );
  247. }
  248. return fSt;
  249. }
  250. BOOL
  251. CIPMap::Load(
  252. HKEY hKey,
  253. LPSTR pszRegKey,
  254. LPSTR pszRegValue
  255. )
  256. /*++
  257. Routine Description:
  258. Load a CIPMap from registry
  259. Arguments:
  260. hKey - registry handle where to open key to read value
  261. pszRegKey - key where to read value
  262. pszRegValue - value name
  263. Return Value:
  264. TRUE if success, otherwise FALSE
  265. --*/
  266. {
  267. CStoreXBF xbf;
  268. return LoadBlobFromReg( hKey,
  269. pszRegKey,
  270. pszRegValue,
  271. &xbf ) &&
  272. Unserialize( &xbf );
  273. }
  274. BOOL
  275. SaveBlobToReg(
  276. HKEY hKey,
  277. LPSTR pszRegKey,
  278. LPSTR pszRegValue,
  279. CStoreXBF* pX
  280. )
  281. /*++
  282. Routine Description:
  283. Save a buffer to registry
  284. Arguments:
  285. hKey - registry handle where to open key to write value
  286. pszRegKey - key where to write value
  287. pszRegValue - value name
  288. pX - ptr to buffer
  289. Return Value:
  290. TRUE if success, otherwise FALSE
  291. --*/
  292. {
  293. BOOL fSt = FALSE;
  294. HKEY hK;
  295. DWORD dwDisposition;
  296. DWORD dwStatus;
  297. if ( (dwStatus = RegCreateKeyEx( hKey,
  298. pszRegKey,
  299. 0,
  300. "",
  301. REG_OPTION_NON_VOLATILE,
  302. KEY_WRITE,
  303. NULL,
  304. &hK,
  305. &dwDisposition )) == ERROR_SUCCESS )
  306. {
  307. if ( (dwStatus = RegSetValueEx( hK,
  308. pszRegValue,
  309. 0,
  310. REG_BINARY,
  311. pX->GetBuff(),
  312. pX->GetUsed() )) == ERROR_SUCCESS )
  313. {
  314. fSt = TRUE;
  315. }
  316. RegCloseKey( hK );
  317. }
  318. if ( !fSt )
  319. {
  320. SetLastError( dwStatus );
  321. }
  322. return fSt;
  323. }
  324. BOOL
  325. CIPMap::Save(
  326. HKEY hKey,
  327. LPSTR pszRegKey,
  328. LPSTR pszRegValue
  329. )
  330. /*++
  331. Routine Description:
  332. Save a CIPMap to registry
  333. Arguments:
  334. hKey - registry handle where to open key to write value
  335. pszRegKey - key where to write value
  336. pszRegValue - value name
  337. Return Value:
  338. TRUE if success, otherwise FALSE
  339. --*/
  340. {
  341. CStoreXBF xbf;
  342. return Serialize( &xbf ) &&
  343. SaveBlobToReg( hKey, pszRegKey, pszRegValue, &xbf );
  344. }
  345. BOOL
  346. CIPMap::AddComputer(
  347. LPWSTR pszName
  348. )
  349. /*++
  350. Routine Description:
  351. Add a computer in CIPMap
  352. Arguments:
  353. pszName - computer name to be added at the end of computer list
  354. Return Value:
  355. TRUE if success, otherwise FALSE
  356. --*/
  357. {
  358. CComputerBalanceCnfg* pComp;
  359. UINT iComp;
  360. LPWSTR pszCheckName;
  361. for ( iComp = 0 ;
  362. iComp < m_Servers.GetNbPtr() ;
  363. ++iComp )
  364. {
  365. if ( ((CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ))->GetName( &pszCheckName ) &&
  366. !_wcsicmp( pszCheckName, pszName ) )
  367. {
  368. SetLastError( ERROR_ALREADY_EXISTS );
  369. return FALSE;
  370. }
  371. }
  372. if ( (pComp = new CComputerBalanceCnfg) &&
  373. m_Servers.AddPtr( (LPVOID)pComp ) != INDEX_ERROR &&
  374. pComp->Init( pszName, m_IpPublic.GetNbEntry() ) )
  375. {
  376. return TRUE;
  377. }
  378. delete pComp;
  379. return FALSE;
  380. }
  381. BOOL
  382. CIPMap::EnumComputer(
  383. UINT iComp,
  384. LPWSTR* ppszName
  385. )
  386. /*++
  387. Routine Description:
  388. Enumerate computers in CIPMap
  389. Arguments:
  390. iComp - computer index ( 0-based )
  391. ppszName - updated with read-only computer name on success
  392. Return Value:
  393. TRUE if success, otherwise FALSE
  394. LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
  395. --*/
  396. {
  397. if ( iComp >= m_Servers.GetNbPtr() )
  398. {
  399. SetLastError( ERROR_NO_MORE_ITEMS );
  400. return FALSE;
  401. }
  402. return ((CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ))->GetName( ppszName );
  403. }
  404. BOOL
  405. CIPMap::DeleteComputer(
  406. UINT iComp
  407. )
  408. /*++
  409. Routine Description:
  410. Delete a computer in CIPMap
  411. Arguments:
  412. iComp - computer index ( 0-based )
  413. Return Value:
  414. TRUE if success, otherwise FALSE
  415. --*/
  416. {
  417. if ( iComp >= m_Servers.GetNbPtr() )
  418. {
  419. return FALSE;
  420. }
  421. delete ((CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ));
  422. return m_Servers.DeletePtr( iComp );
  423. }
  424. BOOL
  425. CIPMap::AddIpPublic(
  426. LPWSTR pszIpPublic,
  427. LPWSTR pszName,
  428. DWORD dwSticky,
  429. DWORD dwAttr
  430. )
  431. /*++
  432. Routine Description:
  433. Add a public IP address in CIPMap
  434. Arguments:
  435. pszIpPublic - public IP address to be added at the end of public IP address list
  436. pszName - name associated with IP address
  437. dwSticky - sticky duration ( in seconds )
  438. dwAttr - user defined param
  439. Return Value:
  440. TRUE if success, otherwise FALSE
  441. --*/
  442. {
  443. UINT iComp;
  444. UINT iIp;
  445. for ( iIp = 0 ;
  446. iIp < m_IpPublic.GetNbPtr() ;
  447. ++iIp )
  448. {
  449. if ( !_wcsicmp( m_IpPublic.GetEntry( iIp ), pszIpPublic ) )
  450. {
  451. SetLastError( ERROR_ALREADY_EXISTS );
  452. return FALSE;
  453. }
  454. }
  455. if ( m_IpPublic.AddEntry( pszIpPublic ) == INDEX_ERROR ||
  456. m_Name.AddEntry( pszName ) == INDEX_ERROR ||
  457. m_Sticky.AddPtr( (LPVOID)dwSticky) == INDEX_ERROR ||
  458. m_Attr.AddPtr( (LPVOID)dwAttr) == INDEX_ERROR )
  459. {
  460. return FALSE;
  461. }
  462. for ( iComp = 0 ;
  463. iComp < m_Servers.GetNbPtr() ;
  464. ++iComp )
  465. {
  466. if ( ((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->AddIpPublic() == INDEX_ERROR )
  467. {
  468. return FALSE;
  469. }
  470. }
  471. return TRUE;
  472. }
  473. BOOL
  474. CIPMap::EnumIpPublic(
  475. UINT iIpPublic,
  476. LPWSTR* ppszIpPublic,
  477. LPWSTR* ppszName,
  478. LPDWORD pdwSticky,
  479. LPDWORD pdwAttr
  480. )
  481. /*++
  482. Routine Description:
  483. Enumerate public IP addresses in CIPMap
  484. Arguments:
  485. iIpPublic - public IP address index ( 0-based )
  486. ppszIpPublic - updated with read-only public IP address on success
  487. ppszName - associated name
  488. pdwSticky - associated sticky duration
  489. pdwAttr - associated user attr
  490. Return Value:
  491. TRUE if success, otherwise FALSE
  492. LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
  493. --*/
  494. {
  495. if ( iIpPublic >= m_IpPublic.GetNbEntry() )
  496. {
  497. SetLastError( ERROR_NO_MORE_ITEMS );
  498. return FALSE;
  499. }
  500. *ppszIpPublic = m_IpPublic.GetEntry( iIpPublic );
  501. *ppszName = m_Name.GetEntry( iIpPublic );
  502. *pdwSticky = (DWORD)m_Sticky.GetPtr( iIpPublic ); // BUGBUG64
  503. *pdwAttr = (DWORD)m_Attr.GetPtr( iIpPublic ); // BUGBUG64
  504. return TRUE;
  505. }
  506. BOOL
  507. CIPMap::DeleteIpPublic(
  508. UINT iIpPublic
  509. )
  510. /*++
  511. Routine Description:
  512. Delete a public IP address in CIPMap
  513. Arguments:
  514. iIpPublic - public IP address index ( 0-based )
  515. Return Value:
  516. TRUE if success, otherwise FALSE
  517. --*/
  518. {
  519. UINT iComp;
  520. if ( !m_IpPublic.DeleteEntry( iIpPublic ) ||
  521. !m_Name.DeleteEntry( iIpPublic ) ||
  522. !m_Sticky.DeletePtr( iIpPublic ) ||
  523. !m_Attr.DeletePtr( iIpPublic ) )
  524. {
  525. return FALSE;
  526. }
  527. for ( iComp = 0 ;
  528. iComp < m_Servers.GetNbPtr() ;
  529. ++iComp )
  530. {
  531. if ( !((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->DeleteIpPublic(iIpPublic) )
  532. {
  533. return FALSE;
  534. }
  535. }
  536. return TRUE;
  537. }
  538. BOOL
  539. CIPMap::SetIpPrivate(
  540. UINT iComp,
  541. UINT iIpPublic,
  542. LPWSTR pszIpPrivate,
  543. LPWSTR pszName
  544. )
  545. /*++
  546. Routine Description:
  547. Set a private IP address in CIPMap
  548. Arguments:
  549. iComp - computer index
  550. iIpPublic - public IP address index
  551. pszIpPrivate - private IP addresse to associate with iComp & iIpPublic
  552. pszName - name associated with private IP address
  553. Return Value:
  554. TRUE if success, otherwise FALSE
  555. LastError will be set to ERROR_INVALID_PARAMETER if indexes out of range
  556. --*/
  557. {
  558. if ( iIpPublic >= m_IpPublic.GetNbEntry() ||
  559. iComp >= m_Servers.GetNbPtr() )
  560. {
  561. SetLastError( ERROR_INVALID_PARAMETER );
  562. return FALSE;
  563. }
  564. return ((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->
  565. SetIpPrivate( iIpPublic, pszIpPrivate, pszName);
  566. }
  567. BOOL
  568. CIPMap::GetIpPrivate(
  569. UINT iComp,
  570. UINT iIpPublic,
  571. LPWSTR* ppszIpPrivate,
  572. LPWSTR* ppszName
  573. )
  574. /*++
  575. Routine Description:
  576. Get a private IP address in CIPMap
  577. Arguments:
  578. iComp - computer index
  579. iIpPublic - public IP address index
  580. ppszIpPrivate - updated with read-only private IP addresse associated with iComp & iIpPublic
  581. ppszName - updated with read-pnly name associated with iComp & iIpPublic
  582. Return Value:
  583. TRUE if success, otherwise FALSE
  584. LastError will be set to ERROR_INVALID_PARAMETER if indexes out of range
  585. --*/
  586. {
  587. if ( iIpPublic >= m_IpPublic.GetNbEntry() ||
  588. iComp >= m_Servers.GetNbPtr() )
  589. {
  590. SetLastError( ERROR_INVALID_PARAMETER );
  591. return FALSE;
  592. }
  593. return ((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->GetIpPrivate(iIpPublic,ppszIpPrivate,ppszName);
  594. }
  595. BOOL
  596. CComputerBalanceCnfg::Init(
  597. LPWSTR pszName,
  598. UINT cIpPublic
  599. )
  600. /*++
  601. Routine Description:
  602. Initialize a CComputerBalanceCnfg with computer name, creating cIpPublic entries
  603. in private IP addresses list
  604. Arguments:
  605. pszName - computer name
  606. cIpPublic - count of current public IP addresses
  607. Return Value:
  608. TRUE if success, otherwise FALSE
  609. --*/
  610. {
  611. if ( !m_ComputerName.Set( pszName ) )
  612. {
  613. return FALSE;
  614. }
  615. while ( cIpPublic-- )
  616. {
  617. if ( m_IpPrivate.AddEntry(L"") == INDEX_ERROR ||
  618. m_Name.AddEntry(L"") == INDEX_ERROR )
  619. {
  620. return FALSE;
  621. }
  622. }
  623. return TRUE;
  624. }
  625. CComputerPerfCounters::CComputerPerfCounters()
  626. /*++
  627. Routine Description:
  628. CComputerPerfCounters constructor
  629. Arguments:
  630. none
  631. Return Value:
  632. nothing
  633. --*/
  634. {
  635. }
  636. CComputerPerfCounters::~CComputerPerfCounters()
  637. /*++
  638. Routine Description:
  639. CComputerPerfCounters destructor
  640. Arguments:
  641. none
  642. Return Value:
  643. nothing
  644. --*/
  645. {
  646. Reset();
  647. }
  648. VOID
  649. CComputerPerfCounters::Reset(
  650. )
  651. /*++
  652. Routine Description:
  653. Reset a CIPMap to empty content
  654. Arguments:
  655. none
  656. Return Value:
  657. nothing
  658. --*/
  659. {
  660. m_PerfCounters.Reset();
  661. m_Weight.Reset();
  662. }
  663. BOOL
  664. CComputerPerfCounters::Serialize(
  665. CStoreXBF* pX
  666. )
  667. /*++
  668. Routine Description:
  669. serialize a CComputerPerfCounters to buffer
  670. Arguments:
  671. buffer where to serialize
  672. Return Value:
  673. TRUE if success, otherwise FALSE
  674. --*/
  675. {
  676. if ( !::Serialize( pX, (DWORD)PERFLIST_VERSION ) )
  677. {
  678. return FALSE;
  679. }
  680. return ::Serialize( pX, (DWORD)m_PerfCounters.GetNbEntry() ) &&
  681. m_PerfCounterServers.Serialize( pX ) &&
  682. m_PerfCounters.Serialize( pX ) &&
  683. m_Weight.Serialize( pX );
  684. }
  685. BOOL
  686. CComputerPerfCounters::Unserialize(
  687. CStoreXBF* pX
  688. )
  689. /*++
  690. Routine Description:
  691. Unserialize a CComputerPerfCounters
  692. Arguments:
  693. pX - ptr to buffer
  694. Return Value:
  695. TRUE if success, otherwise FALSE
  696. --*/
  697. {
  698. LPBYTE pb = pX->GetBuff();
  699. DWORD dw = pX->GetUsed();
  700. return Unserialize( &pb, &dw );
  701. }
  702. BOOL
  703. CComputerPerfCounters::Unserialize(
  704. LPBYTE* ppb,
  705. LPDWORD pdw
  706. )
  707. /*++
  708. Routine Description:
  709. Unserialize a CComputerPerfCounters
  710. Arguments:
  711. ppB - ptr to addr of buffer to unserialize from
  712. pC - ptr to count of bytes in buffer
  713. Return Value:
  714. TRUE if success, otherwise FALSE
  715. --*/
  716. {
  717. DWORD dwP;
  718. DWORD dwVersion;
  719. if ( !::Unserialize( ppb, pdw, &dwVersion ) )
  720. {
  721. return FALSE;
  722. }
  723. return ::Unserialize( ppb, pdw, &dwP ) &&
  724. m_PerfCounterServers.Unserialize( ppb, pdw, dwP ) &&
  725. m_PerfCounters.Unserialize( ppb, pdw, dwP ) &&
  726. m_Weight.Unserialize( ppb, pdw, dwP );
  727. }
  728. BOOL
  729. CComputerPerfCounters::Load(
  730. HKEY hKey,
  731. LPSTR pszRegKey,
  732. LPSTR pszRegValue
  733. )
  734. /*++
  735. Routine Description:
  736. Load a CComputerPerfCounters from registry
  737. Arguments:
  738. hKey - registry handle where to open key to read value
  739. pszRegKey - key where to read value
  740. pszRegValue - value name
  741. Return Value:
  742. TRUE if success, otherwise FALSE
  743. --*/
  744. {
  745. CStoreXBF xbf;
  746. return LoadBlobFromReg( hKey,
  747. pszRegKey,
  748. pszRegValue,
  749. &xbf ) &&
  750. Unserialize( &xbf );
  751. }
  752. BOOL
  753. CComputerPerfCounters::Save(
  754. HKEY hKey,
  755. LPSTR pszRegKey,
  756. LPSTR pszRegValue
  757. )
  758. /*++
  759. Routine Description:
  760. Save a CComputerPerfCounters to registry
  761. Arguments:
  762. hKey - registry handle where to open key to write value
  763. pszRegKey - key where to write value
  764. pszRegValue - value name
  765. Return Value:
  766. TRUE if success, otherwise FALSE
  767. --*/
  768. {
  769. CStoreXBF xbf;
  770. return Serialize( &xbf ) &&
  771. SaveBlobToReg( hKey, pszRegKey, pszRegValue, &xbf );
  772. }
  773. BOOL
  774. CComputerPerfCounters::AddPerfCounter(
  775. LPWSTR pszServerName,
  776. LPWSTR pszPerfCounter,
  777. DWORD dwWeight
  778. )
  779. /*++
  780. Routine Description:
  781. Add a performance counter in CIPMap
  782. Arguments:
  783. pszServerName - optional server name ( can be NULL )
  784. pszIpPublic - performance counter to be added at the end of performance counter list
  785. dwWeight - weight associated with perf counter to add
  786. Return Value:
  787. TRUE if success, otherwise FALSE
  788. --*/
  789. {
  790. UINT iPerf;
  791. //
  792. // Check if specify normalized flag then to other counter exist.
  793. // if not normalized then existing counter should not be normalized.
  794. //
  795. if ( dwWeight == LB_WEIGHT_NORMALIZED_FLAG &&
  796. m_PerfCounterServers.GetNbEntry() )
  797. {
  798. SetLastError( ERROR_INVALID_PARAMETER );
  799. return FALSE;
  800. }
  801. else if ( dwWeight != LB_WEIGHT_NORMALIZED_FLAG )
  802. {
  803. for ( iPerf = 0 ;
  804. iPerf < m_PerfCounters.GetNbEntry() ;
  805. ++iPerf )
  806. {
  807. if ( (DWORD)m_Weight.GetPtr( iPerf ) == LB_WEIGHT_NORMALIZED_FLAG ) // BUGBUG64
  808. {
  809. SetLastError( ERROR_INVALID_PARAMETER );
  810. return FALSE;
  811. }
  812. }
  813. }
  814. return m_PerfCounterServers.AddEntry( pszServerName ? pszServerName : L"") != INDEX_ERROR &&
  815. m_PerfCounters.AddEntry( pszPerfCounter ) != INDEX_ERROR &&
  816. m_Weight.AddPtr( (LPVOID)dwWeight ) != INDEX_ERROR;
  817. }
  818. BOOL
  819. CComputerPerfCounters::EnumPerfCounter(
  820. UINT iPerfCounter,
  821. LPWSTR* ppszPerfCounterServer,
  822. LPWSTR* ppszPerfCounter,
  823. DWORD* pdwWeight
  824. )
  825. /*++
  826. Routine Description:
  827. Enumerate performance counters in CComputerPerfCounters
  828. Arguments:
  829. iPerfCounter - public IP address index ( 0-based )
  830. ppszServerName - updated with read-only server name ( can be NULL )
  831. ppszPerfCounter - updated with read-only performance counter on success
  832. pdwWeight - updated with read-only perf counter weight on success
  833. Return Value:
  834. TRUE if success, otherwise FALSE
  835. LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
  836. --*/
  837. {
  838. if ( iPerfCounter >= m_PerfCounters.GetNbEntry() )
  839. {
  840. SetLastError( ERROR_NO_MORE_ITEMS );
  841. return FALSE;
  842. }
  843. *ppszPerfCounterServer = *m_PerfCounterServers.GetEntry( iPerfCounter ) ?
  844. m_PerfCounterServers.GetEntry( iPerfCounter ) :
  845. NULL;
  846. *ppszPerfCounter = m_PerfCounters.GetEntry( iPerfCounter );
  847. *pdwWeight = (DWORD)m_Weight.GetPtr( iPerfCounter ); // BUGBUG64
  848. return TRUE;
  849. }
  850. BOOL
  851. CComputerPerfCounters::DeletePerfCounter(
  852. UINT iPerfCounter
  853. )
  854. /*++
  855. Routine Description:
  856. Delete a performance counter in CComputerPerfCounters
  857. Arguments:
  858. iPerfCounter - performance counter index ( 0-based )
  859. Return Value:
  860. TRUE if success, otherwise FALSE
  861. --*/
  862. {
  863. return m_PerfCounterServers.DeleteEntry( iPerfCounter ) &&
  864. m_PerfCounters.DeleteEntry( iPerfCounter ) &&
  865. m_Weight.DeletePtr( iPerfCounter );
  866. }
  867. BOOL
  868. CComputerPerfCounters::SetPerfCounterWeight(
  869. UINT iPerfCounter,
  870. DWORD dwWeight
  871. )
  872. /*++
  873. Routine Description:
  874. Set a performance counter weight in CIPMap
  875. Arguments:
  876. iPerfCounter - performance counter index
  877. dwWeight - weight to associate with performance counter indexed by iPerfCounter
  878. Return Value:
  879. TRUE if success, otherwise FALSE
  880. --*/
  881. {
  882. return m_Weight.SetPtr( iPerfCounter, (LPVOID)dwWeight );
  883. }
  884. /////////////////
  885. CIpEndpointList::CIpEndpointList(
  886. )
  887. /*++
  888. Routine Description:
  889. CIpEndpointList constructor
  890. Arguments:
  891. none
  892. Return Value:
  893. nothing
  894. --*/
  895. {
  896. }
  897. CIpEndpointList::~CIpEndpointList(
  898. )
  899. /*++
  900. Routine Description:
  901. CIpEndpointList destructor
  902. Arguments:
  903. none
  904. Return Value:
  905. nothing
  906. --*/
  907. {
  908. Reset();
  909. }
  910. VOID
  911. CIpEndpointList::Reset(
  912. )
  913. /*++
  914. Routine Description:
  915. Reset a CIpEndpointList to empty content
  916. Arguments:
  917. none
  918. Return Value:
  919. nothing
  920. --*/
  921. {
  922. UINT iComp;
  923. m_IpEndpoint.Reset();
  924. }
  925. BOOL
  926. CIpEndpointList::Serialize(
  927. CStoreXBF* pX
  928. )
  929. /*++
  930. Routine Description:
  931. serialize a CIpEndpointList to buffer
  932. Arguments:
  933. buffer where to serialize
  934. Return Value:
  935. TRUE if success, otherwise FALSE
  936. --*/
  937. {
  938. if ( !::Serialize( pX, (DWORD)m_IpEndpoint.GetNbEntry() ) )
  939. {
  940. return FALSE;
  941. }
  942. if ( !m_IpEndpoint.Serialize( pX ) )
  943. {
  944. return FALSE;
  945. }
  946. return TRUE;
  947. }
  948. BOOL
  949. CIpEndpointList::Unserialize(
  950. CStoreXBF* pX
  951. )
  952. /*++
  953. Routine Description:
  954. Unserialize a CIpEndpointList
  955. Arguments:
  956. pX - ptr to buffer
  957. Return Value:
  958. TRUE if success, otherwise FALSE
  959. --*/
  960. {
  961. LPBYTE pb = pX->GetBuff();
  962. DWORD dw = pX->GetUsed();
  963. return Unserialize( &pb, &dw );
  964. }
  965. BOOL
  966. CIpEndpointList::Unserialize(
  967. LPBYTE* ppb,
  968. LPDWORD pc
  969. )
  970. /*++
  971. Routine Description:
  972. Unserialize CIpEndpointList
  973. Arguments:
  974. ppb - ptr to addr of buffer to unserialize from
  975. pc - ptr to count of bytes in buffer
  976. Return Value:
  977. TRUE if success, otherwise FALSE
  978. --*/
  979. {
  980. DWORD dwIp;
  981. Reset();
  982. if ( !::Unserialize( ppb, pc, &dwIp ) )
  983. {
  984. return FALSE;
  985. }
  986. if ( !m_IpEndpoint.Unserialize( ppb, pc, dwIp ) )
  987. {
  988. return FALSE;
  989. }
  990. return TRUE;
  991. }
  992. BOOL
  993. CIpEndpointList::EnumIpEndpoint(
  994. UINT iIp,
  995. LPWSTR* ppszIp
  996. )
  997. /*++
  998. Routine Description:
  999. Enumerate IP endpoints
  1000. Arguments:
  1001. iIp - IP index ( 0-based )
  1002. ppszName - updated with read-only IP addr ( as string ) on success
  1003. Return Value:
  1004. TRUE if success, otherwise FALSE
  1005. LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
  1006. --*/
  1007. {
  1008. if ( iIp >= m_IpEndpoint.GetNbEntry() )
  1009. {
  1010. SetLastError( ERROR_NO_MORE_ITEMS );
  1011. return FALSE;
  1012. }
  1013. *ppszIp = m_IpEndpoint.GetEntry( iIp );
  1014. return TRUE;
  1015. }
  1016. BOOL
  1017. CIpEndpointList::BuildListFromLocalhost(
  1018. )
  1019. /*++
  1020. Routine Description:
  1021. Build list of local IP endpoints
  1022. Arguments:
  1023. None
  1024. Return Value:
  1025. TRUE if success, otherwise FALSE
  1026. --*/
  1027. {
  1028. char** pAddr;
  1029. sockaddr_in SockAddr;
  1030. struct hostent* pH;
  1031. WCHAR achAddr[128];
  1032. DWORD cAddr;
  1033. Reset();
  1034. if ( pH = gethostbyname( NULL ) )
  1035. {
  1036. if ( pH->h_addrtype == AF_INET )
  1037. {
  1038. for ( pAddr = pH->h_addr_list;
  1039. *pAddr ;
  1040. ++pAddr )
  1041. {
  1042. memcpy( &SockAddr.sin_addr, *pAddr, 4 );
  1043. SockAddr.sin_family = AF_INET;
  1044. SockAddr.sin_port = 0;
  1045. cAddr = sizeof( achAddr ) / sizeof(WCHAR);
  1046. if ( WSAAddressToStringW( (struct sockaddr *)&SockAddr,
  1047. sizeof(SockAddr),
  1048. NULL,
  1049. achAddr,
  1050. &cAddr ) != 0 ||
  1051. m_IpEndpoint.AddEntry( achAddr ) == INDEX_ERROR )
  1052. {
  1053. return FALSE;
  1054. }
  1055. }
  1056. return TRUE;
  1057. }
  1058. else
  1059. {
  1060. SetLastError( ERROR_INVALID_PARAMETER );
  1061. return FALSE;
  1062. }
  1063. }
  1064. return FALSE;
  1065. }