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.

3133 lines
77 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: control.cpp
  4. //
  5. // Module:
  6. //
  7. // Description: Implement class CWlbsControl
  8. //
  9. // Copyright (C) Microsoft Corporation. All rights reserved.
  10. //
  11. // Author: Created 3/2/00
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "precomp.h"
  15. #include <debug.h>
  16. #include "cluster.h"
  17. #include "control.h"
  18. #include "param.h"
  19. #include "control.tmh" // for event tracing
  20. //
  21. // Global variable for the dll instance
  22. //
  23. HINSTANCE g_hInstCtrl;
  24. //
  25. // Helper functions
  26. //
  27. DWORD MapStateFromDriverToApi(DWORD dwDriverState);
  28. //+----------------------------------------------------------------------------
  29. //
  30. // Function: IsLocalHost
  31. //
  32. // Description:
  33. //
  34. // Arguments: CWlbsCluster* pCluster -
  35. // DWORD dwHostID -
  36. //
  37. // Returns: inline bool -
  38. //
  39. // History: fengsun Created Header 3/2/00
  40. //
  41. //+----------------------------------------------------------------------------
  42. inline bool IsLocalHost(CWlbsCluster* pCluster, DWORD dwHostID)
  43. {
  44. if (pCluster == NULL)
  45. {
  46. return false;
  47. }
  48. return dwHostID == WLBS_LOCAL_HOST; // || pCluster->GetHostID() == dwHostID;
  49. }
  50. //+----------------------------------------------------------------------------
  51. //
  52. // Function: QueryPortFromSocket
  53. //
  54. // Synopsis:
  55. // This routine retrieves the port number to which a socket is bound.
  56. //
  57. // Arguments:
  58. // Socket - the socket to be queried
  59. //
  60. // Return Value:
  61. // USHORT - the port number retrieved
  62. //
  63. // History: Created Header 2/10/99
  64. //
  65. //+----------------------------------------------------------------------------
  66. static USHORT QueryPortFromSocket(SOCKET Socket)
  67. {
  68. SOCKADDR_IN Address;
  69. int AddressLength;
  70. AddressLength = sizeof(Address);
  71. getsockname(Socket, (PSOCKADDR)&Address, &AddressLength);
  72. return Address.sin_port;
  73. }
  74. //+----------------------------------------------------------------------------
  75. //
  76. // Function: CWlbsControl::CWlbsControl
  77. //
  78. // Description:
  79. //
  80. // Arguments: None
  81. //
  82. // Returns: Nothing
  83. //
  84. // History: fengsun Created Header 3/2/00
  85. //
  86. //+----------------------------------------------------------------------------
  87. CWlbsControl::CWlbsControl()
  88. {
  89. m_local_ctrl = FALSE;
  90. m_remote_ctrl = FALSE;
  91. m_hdl = INVALID_HANDLE_VALUE;
  92. m_registry_lock = INVALID_HANDLE_VALUE;
  93. m_def_dst_addr = 0;
  94. m_def_timeout = IOCTL_REMOTE_RECV_DELAY;
  95. m_def_port = CVY_DEF_RCT_PORT;
  96. m_def_passw = CVY_DEF_RCT_PASSWORD;
  97. m_dwNumCluster = 0;
  98. for (int i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  99. {
  100. m_cluster_params [i] . cluster = 0;
  101. m_cluster_params [i] . passw = CVY_DEF_RCT_PASSWORD;
  102. m_cluster_params [i] . timeout = IOCTL_REMOTE_RECV_DELAY;
  103. m_cluster_params [i] . port = CVY_DEF_RCT_PORT;
  104. m_cluster_params [i] . dest = 0;
  105. }
  106. ZeroMemory(m_pClusterArray, sizeof(m_pClusterArray));
  107. }
  108. //+----------------------------------------------------------------------------
  109. //
  110. // Function: CWlbsControl::~CWlbsControl
  111. //
  112. // Description:
  113. //
  114. // Arguments: None
  115. //
  116. // Returns: Nothing
  117. //
  118. // History: fengsun Created Header 3/2/00
  119. //
  120. //+----------------------------------------------------------------------------
  121. CWlbsControl::~CWlbsControl()
  122. {
  123. for (DWORD i=0; i< m_dwNumCluster; i++)
  124. {
  125. delete m_pClusterArray[i];
  126. }
  127. if (m_hdl)
  128. {
  129. CloseHandle(m_hdl);
  130. }
  131. if (m_remote_ctrl)
  132. {
  133. WSACleanup(); // WSAStartup is called in Initialize()
  134. }
  135. }
  136. //+----------------------------------------------------------------------------
  137. //
  138. // Function: CWlbsControl::Initialize
  139. //
  140. // Description: Initialization
  141. //
  142. // Arguments: None
  143. //
  144. // Returns: bool - true if succeeded
  145. //
  146. // History: fengsun Created Header 1/25/00
  147. //
  148. //+----------------------------------------------------------------------------
  149. DWORD CWlbsControl::Initialize()
  150. {
  151. WORD ver;
  152. int ret;
  153. if (IsInitialized())
  154. {
  155. ReInitialize();
  156. return GetInitResult();
  157. }
  158. _tsetlocale (LC_ALL, _TEXT(".OCP"));
  159. /* open Winsock */
  160. WSADATA data;
  161. if (WSAStartup (WINSOCK_VERSION, & data) == 0)
  162. {
  163. /* figure out client IP address */
  164. CHAR buf [CVY_STR_SIZE];
  165. ret = gethostname (buf, CVY_STR_SIZE);
  166. if (ret != SOCKET_ERROR)
  167. {
  168. struct hostent * host;
  169. host = gethostbyname (buf);
  170. m_dwSrcAddress = 0;
  171. if ( host && ((struct in_addr *) (host -> h_addr)) -> s_addr != 0)
  172. {
  173. m_remote_ctrl = TRUE;
  174. m_dwSrcAddress = ((struct in_addr *) (host -> h_addr)) -> s_addr;
  175. }
  176. }
  177. if (!m_remote_ctrl)
  178. {
  179. LOG_ERROR1("CWlbsControl::Initialize failed. gethostname return %d", ret);
  180. WSACleanup();
  181. }
  182. }
  183. /* if succeeded querying local parameters - connect to device */
  184. if (m_hdl != INVALID_HANDLE_VALUE)
  185. CloseHandle (m_hdl);
  186. m_hdl = CreateFile (_TEXT("\\\\.\\WLBS"), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
  187. if (m_hdl == INVALID_HANDLE_VALUE)
  188. {
  189. LOG_ERROR1("CWlbsControl::Initialize failed to open wlbs device %d", GetLastError());
  190. return GetInitResult();
  191. }
  192. else
  193. {
  194. m_local_ctrl = TRUE;
  195. }
  196. //
  197. // enumerate clusters
  198. //
  199. HKEY hKeyWlbs;
  200. DWORD dwError;
  201. dwError = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  202. L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface",
  203. 0L, KEY_READ, & hKeyWlbs);
  204. if (dwError != ERROR_SUCCESS)
  205. {
  206. return GetInitResult();
  207. }
  208. m_dwNumCluster = 0;
  209. for (int index=0;;index++)
  210. {
  211. WCHAR szAdapterGuid[128];
  212. DWORD dwSize = sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]);
  213. dwError = RegEnumKeyEx(hKeyWlbs, index,
  214. szAdapterGuid, &dwSize,
  215. NULL, NULL, NULL, NULL);
  216. if (dwError != ERROR_SUCCESS)
  217. {
  218. if (dwError != ERROR_NO_MORE_ITEMS)
  219. {
  220. LOG_ERROR1("CWlbsControl::Initialize failed at RegEnumKeyEx %d", dwError);
  221. }
  222. break;
  223. }
  224. GUID AdapterGuid;
  225. HRESULT hr = CLSIDFromString(szAdapterGuid, &AdapterGuid);
  226. if (FAILED(hr))
  227. {
  228. LOG_ERROR1("CWlbsControl::Initialize failed at CLSIDFromString %s", szAdapterGuid);
  229. continue;
  230. }
  231. IOCTL_CVY_BUF in_buf;
  232. IOCTL_CVY_BUF out_buf;
  233. DWORD status = WlbsLocalControl (m_hdl, AdapterGuid,
  234. IOCTL_CVY_QUERY, & in_buf, & out_buf, 0);
  235. if (status == WLBS_IO_ERROR)
  236. {
  237. continue;
  238. }
  239. //
  240. // Use index instead of m_dwNumCluster as the cluster index
  241. // m_dwNumCluster will change is a adapter get unbound.
  242. // index will change only if an adapter get removed
  243. //
  244. m_pClusterArray[m_dwNumCluster] = new CWlbsCluster(index);
  245. if (m_pClusterArray[m_dwNumCluster] == NULL)
  246. {
  247. LOG_ERROR("CWlbsControl::Initialize failed to allocate memory");
  248. ASSERT(m_pClusterArray[m_dwNumCluster]);
  249. }
  250. else
  251. {
  252. m_pClusterArray[m_dwNumCluster]->Initialize(AdapterGuid);
  253. m_dwNumCluster++;
  254. }
  255. }
  256. RegCloseKey(hKeyWlbs);
  257. return GetInitResult();
  258. }
  259. //+----------------------------------------------------------------------------
  260. //
  261. // Function: CWlbsControl::ReInitialize
  262. //
  263. // Description: Re-Initialization to get the current cluster list
  264. //
  265. // Arguments: None
  266. //
  267. // Returns: bool - true if succeeded
  268. //
  269. // History: fengsun Created Header 1/25/00
  270. //
  271. //+----------------------------------------------------------------------------
  272. bool CWlbsControl::ReInitialize()
  273. {
  274. ASSERT(m_hdl != INVALID_HANDLE_VALUE);
  275. if ( m_hdl == INVALID_HANDLE_VALUE )
  276. {
  277. return false;
  278. }
  279. HKEY hKeyWlbs;
  280. DWORD dwError;
  281. dwError = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  282. L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface",
  283. 0L, KEY_READ, & hKeyWlbs);
  284. if (dwError != ERROR_SUCCESS)
  285. {
  286. LOG_ERROR("CWlbsControl::Initialize failed at RegOpenKeyEx");
  287. return false;
  288. }
  289. //
  290. // Re enumerate the clusters
  291. //
  292. DWORD dwNewNumCluster = 0; // the number of new clusters
  293. bool fClusterExists[WLBS_MAX_CLUSTERS];
  294. CWlbsCluster* NewClusterArray[WLBS_MAX_CLUSTERS];
  295. for (DWORD i=0;i<m_dwNumCluster;i++)
  296. {
  297. fClusterExists[i] = false;
  298. }
  299. for (int index=0;;index++)
  300. {
  301. WCHAR szAdapterGuid[128];
  302. DWORD dwSize = sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]);
  303. dwError = RegEnumKeyEx(hKeyWlbs, index,
  304. szAdapterGuid, &dwSize,
  305. NULL, NULL, NULL, NULL);
  306. if (dwError != ERROR_SUCCESS)
  307. {
  308. if (dwError != ERROR_NO_MORE_ITEMS)
  309. {
  310. LOG_ERROR1("CWlbsControl::Initialize failed at RegEnumKeyEx %d", dwError);
  311. return false;
  312. }
  313. break;
  314. }
  315. GUID AdapterGuid;
  316. HRESULT hr = CLSIDFromString(szAdapterGuid, &AdapterGuid);
  317. if (FAILED(hr))
  318. {
  319. LOG_ERROR1("CWlbsControl::Initialize failed at CLSIDFromString %s", szAdapterGuid);
  320. continue;
  321. }
  322. IOCTL_CVY_BUF in_buf;
  323. IOCTL_CVY_BUF out_buf;
  324. DWORD status = WlbsLocalControl (m_hdl, AdapterGuid,
  325. IOCTL_CVY_QUERY, & in_buf, & out_buf, 0);
  326. if (status == WLBS_IO_ERROR)
  327. {
  328. continue;
  329. }
  330. //
  331. // Check if this is a new adapter
  332. //
  333. for (DWORD j=0; j<m_dwNumCluster; j++)
  334. {
  335. ASSERT(m_pClusterArray[j]);
  336. if (IsEqualGUID(AdapterGuid, m_pClusterArray[j]->GetAdapterGuid()))
  337. {
  338. ASSERT(fClusterExists[j] == false);
  339. fClusterExists[j] = true;
  340. //
  341. // Since adapter could be added or removed, since last time,
  342. // The index could be changed
  343. //
  344. m_pClusterArray[j]->m_dwConfigIndex = index;
  345. break;
  346. }
  347. }
  348. //
  349. // It is a new adapter
  350. //
  351. if (j == m_dwNumCluster)
  352. {
  353. CWlbsCluster* pCluster = new CWlbsCluster(index);
  354. if (pCluster == NULL)
  355. {
  356. LOG_ERROR("CWlbsControl::ReInitialize failed to allocate memory");
  357. ASSERT(pCluster);
  358. }
  359. else
  360. {
  361. pCluster->Initialize(AdapterGuid);
  362. //
  363. // Add
  364. //
  365. NewClusterArray[dwNewNumCluster] = pCluster;
  366. dwNewNumCluster++;
  367. }
  368. }
  369. }
  370. RegCloseKey(hKeyWlbs);
  371. //
  372. // Create the new cluster array
  373. //
  374. for (i=0; i< m_dwNumCluster; i++)
  375. {
  376. if (!fClusterExists[i])
  377. {
  378. delete m_pClusterArray[i];
  379. }
  380. else
  381. {
  382. //
  383. // Reload settings
  384. //
  385. m_pClusterArray[i]->ReInitialize();
  386. NewClusterArray[dwNewNumCluster] = m_pClusterArray[i];
  387. dwNewNumCluster++;
  388. }
  389. m_pClusterArray[i] = NULL;
  390. }
  391. //
  392. // Copy the array back
  393. //
  394. m_dwNumCluster = dwNewNumCluster;
  395. CopyMemory(m_pClusterArray, NewClusterArray, m_dwNumCluster * sizeof(m_pClusterArray[0]));
  396. ASSERT(m_pClusterArray[m_dwNumCluster] == NULL);
  397. return true;
  398. }
  399. //+----------------------------------------------------------------------------
  400. //
  401. // Function: MapStateFromDriverToApi
  402. //
  403. // Description: Map the state return from wlbs driver to the API state
  404. //
  405. // Arguments: DWORD dwDriverState -
  406. //
  407. // Returns: DWORD -
  408. //
  409. // History: fengsun Created Header 1/25/00
  410. //
  411. //+----------------------------------------------------------------------------
  412. DWORD MapStateFromDriverToApi(DWORD dwDriverState)
  413. {
  414. struct STATE_MAP
  415. {
  416. DWORD dwDriverState;
  417. DWORD dwApiState;
  418. } StateMap[] =
  419. {
  420. {IOCTL_CVY_ALREADY, WLBS_ALREADY},
  421. {IOCTL_CVY_BAD_PARAMS, WLBS_BAD_PARAMS},
  422. {IOCTL_CVY_NOT_FOUND, WLBS_NOT_FOUND},
  423. {IOCTL_CVY_STOPPED, WLBS_STOPPED},
  424. {IOCTL_CVY_SUSPENDED, WLBS_SUSPENDED},
  425. {IOCTL_CVY_CONVERGING, WLBS_CONVERGING},
  426. {IOCTL_CVY_SLAVE, WLBS_CONVERGED},
  427. {IOCTL_CVY_MASTER, WLBS_DEFAULT},
  428. {IOCTL_CVY_BAD_PASSWORD, WLBS_BAD_PASSW},
  429. {IOCTL_CVY_DRAINING, WLBS_DRAINING},
  430. {IOCTL_CVY_DRAINING_STOPPED, WLBS_DRAIN_STOP},
  431. {IOCTL_CVY_DISCONNECTED, WLBS_DISCONNECTED},
  432. };
  433. for (int i=0; i<sizeof(StateMap) /sizeof(StateMap[0]); i++)
  434. {
  435. if (StateMap[i].dwDriverState == dwDriverState)
  436. {
  437. return StateMap[i].dwApiState;
  438. }
  439. }
  440. //
  441. // Default
  442. //
  443. return WLBS_OK;
  444. }
  445. //+----------------------------------------------------------------------------
  446. //
  447. // Function: CWlbsControl::GetClusterFromIp
  448. //
  449. // Description: Get the cluster object from IP
  450. //
  451. // Arguments: DWORD dwClusterIp -
  452. //
  453. // Returns: CWlbsCluster* - Caller can NOT free the return object
  454. //
  455. // History: fengsun Created Header 3/9/00
  456. //
  457. //+----------------------------------------------------------------------------
  458. inline
  459. CWlbsCluster* CWlbsControl::GetClusterFromIp(DWORD dwClusterIp)
  460. {
  461. for (DWORD i=0; i< m_dwNumCluster; i++)
  462. {
  463. if(m_pClusterArray[i]->GetClusterIp() == dwClusterIp)
  464. {
  465. return m_pClusterArray[i];
  466. }
  467. }
  468. return NULL;
  469. }
  470. //+----------------------------------------------------------------------------
  471. //
  472. // Function: CWlbsControl::GetClusterFromAdapter
  473. //
  474. // Description: Get the cluster object from adapter guid
  475. //
  476. // Arguments: GUID *pAdapterGuid -- GUID of the adapter.
  477. //
  478. // Returns: CWlbsCluster* - Caller can NOT free the return object
  479. //
  480. // History: JosephJ Created 4/20/01
  481. //
  482. //+----------------------------------------------------------------------------
  483. inline
  484. CWlbsCluster* CWlbsControl::GetClusterFromAdapter(IN const GUID &AdapterGuid)
  485. {
  486. for (DWORD i=0; i< m_dwNumCluster; i++)
  487. {
  488. const GUID& Guid = m_pClusterArray[i]->GetAdapterGuid();
  489. if (IsEqualGUID(Guid, AdapterGuid))
  490. {
  491. return m_pClusterArray[i];
  492. }
  493. }
  494. return NULL;
  495. }
  496. //+----------------------------------------------------------------------------
  497. //
  498. // Function: CWlbsControl::ValidateParam
  499. //
  500. // Description: Validate the specified WLBS cluster parameter. It has no side effects other to munge paramp, for example reformatting
  501. // IP addresses into canonical form.
  502. //
  503. // Arguments: paramp -- params to validate
  504. //
  505. // Returns: TRUE if params look valid, false otherwise.
  506. //
  507. // History: JosephJ Created 4/25/01
  508. //
  509. //+----------------------------------------------------------------------------
  510. BOOL
  511. CWlbsControl::ValidateParam(
  512. IN OUT PWLBS_REG_PARAMS paramp
  513. )
  514. {
  515. return ::ParamValidate(paramp)!=0;
  516. }
  517. //
  518. //
  519. //+----------------------------------------------------------------------------
  520. //
  521. // Function: CWlbsControl::LocalClusterControl
  522. //
  523. // Description: Performs local cluster-wide control operations on the
  524. // specified GUID.
  525. //
  526. // Arguments: AdapterGuid -- GUID of the adapter.
  527. // ioctl -- cluster control ioctl.
  528. //
  529. // Returns: WLBS return code
  530. //
  531. // History: JosephJ Created 4/25/01
  532. //
  533. //+----------------------------------------------------------------------------
  534. DWORD CWlbsControl::LocalClusterControl(
  535. IN const GUID& AdapterGuid,
  536. IN LONG ioctl
  537. )
  538. {
  539. DWORD status;
  540. IOCTL_CVY_BUF in_buf;
  541. IOCTL_CVY_BUF out_buf;
  542. status = GetInitResult();
  543. if (status == WLBS_INIT_ERROR)
  544. {
  545. goto end;
  546. }
  547. //
  548. // We only support cluster-wide operations...
  549. //
  550. switch(ioctl)
  551. {
  552. case IOCTL_CVY_CLUSTER_ON:
  553. break;
  554. case IOCTL_CVY_CLUSTER_OFF:
  555. break;
  556. case IOCTL_CVY_CLUSTER_SUSPEND:
  557. break;
  558. case IOCTL_CVY_CLUSTER_RESUME:
  559. break;
  560. case IOCTL_CVY_CLUSTER_DRAIN:
  561. break;
  562. default:
  563. status = WLBS_BAD_PARAMS;
  564. goto end;
  565. }
  566. ZeroMemory(&in_buf, sizeof(in_buf));
  567. status = WlbsLocalControl (m_hdl, AdapterGuid,
  568. ioctl, & in_buf, & out_buf, 0);
  569. if (status != WLBS_IO_ERROR)
  570. {
  571. status = MapStateFromDriverToApi (out_buf.ret_code);
  572. }
  573. end:
  574. return status;
  575. }
  576. //+----------------------------------------------------------------------------
  577. //
  578. // Function: CWlbsControlWrapper::GetClusterFromIpOrIndex
  579. //
  580. // Description:
  581. //
  582. // Arguments: DWORD dwClusterIpOrIndex -
  583. //
  584. // Returns: CWlbsCluster* -
  585. //
  586. // History: fengsun Created Header 7/3/00
  587. //
  588. //+----------------------------------------------------------------------------
  589. CWlbsCluster* CWlbsControl::GetClusterFromIpOrIndex(DWORD dwClusterIpOrIndex)
  590. {
  591. for (DWORD i=0; i<m_dwNumCluster; i++)
  592. {
  593. if (m_pClusterArray[i]->GetClusterIpOrIndex(this) == dwClusterIpOrIndex)
  594. {
  595. return m_pClusterArray[i];
  596. }
  597. }
  598. return NULL;
  599. }
  600. /*
  601. * Function: CWlbsControlWrapper::IsClusterMember
  602. * Description: This function searches the list of known NLB clusters on this
  603. * host to determine whether or not this host is a member of a
  604. * given cluster.
  605. * Author: shouse, Created 4.16.01
  606. */
  607. BOOLEAN CWlbsControl::IsClusterMember (DWORD dwClusterIp)
  608. {
  609. for (DWORD i = 0; i < m_dwNumCluster; i++) {
  610. if (m_pClusterArray[i]->GetClusterIp() == dwClusterIp)
  611. return TRUE;
  612. }
  613. return FALSE;
  614. }
  615. //+----------------------------------------------------------------------------
  616. //
  617. // Function: CWlbsControl::EnumClusterObjects
  618. //
  619. // Description: Get a list of cluster objects
  620. //
  621. // Arguments: OUT CWlbsCluster** &pdwClusters - The memory is internal to CWlbsControl
  622. /// Caller can NOT free the pdwClusters memory
  623. // OUT DWORD* pdwNum -
  624. //
  625. // Returns: DWORD -
  626. //
  627. // History: fengsun Created Header 3/3/00
  628. //
  629. //+----------------------------------------------------------------------------
  630. DWORD CWlbsControl::EnumClusterObjects(OUT CWlbsCluster** &ppClusters, OUT DWORD* pdwNum)
  631. {
  632. ASSERT(pdwNum);
  633. ppClusters = m_pClusterArray;
  634. *pdwNum = m_dwNumCluster;
  635. return ERROR_SUCCESS;
  636. }
  637. //+----------------------------------------------------------------------------
  638. //
  639. // Function: CWlbsControl::EnumClusters
  640. //
  641. // Description: Get a list of cluster IP or index
  642. //
  643. // Arguments: OUT DWORD* pdwAddresses -
  644. // IN OUT DWORD* pdwNum - IN size of the buffer, OUT element returned
  645. //
  646. // Returns: DWORD - WLBS error code.
  647. //
  648. // History: fengsun Created Header 3/3/00
  649. //
  650. //+----------------------------------------------------------------------------
  651. DWORD CWlbsControl::EnumClusters(OUT DWORD* pdwAddresses, IN OUT DWORD* pdwNum)
  652. {
  653. if (pdwNum == NULL)
  654. {
  655. return WLBS_BAD_PARAMS;
  656. }
  657. if (pdwAddresses == NULL || *pdwNum < m_dwNumCluster)
  658. {
  659. *pdwNum = m_dwNumCluster;
  660. return ERROR_MORE_DATA;
  661. }
  662. *pdwNum = m_dwNumCluster;
  663. for (DWORD i=0; i< m_dwNumCluster; i++)
  664. {
  665. pdwAddresses[i] = m_pClusterArray[i]->GetClusterIpOrIndex(this);
  666. }
  667. return WLBS_OK;
  668. }
  669. //+----------------------------------------------------------------------------
  670. //
  671. // Function: WlbsLocalControl
  672. //
  673. // Description: Send DeviceIoControl to local driver
  674. //
  675. // Arguments: HANDLE hDevice -
  676. // const GUID& AdapterGuid - the guid of the adapter
  677. // LONG ioctl -
  678. // PIOCTL_CVY_BUF in_bufp -
  679. // PIOCTL_CVY_BUF out_bufp -
  680. //
  681. // Returns: DWORD -
  682. //
  683. // History: fengsun Created Header 3/9/00
  684. //
  685. //+----------------------------------------------------------------------------
  686. DWORD WlbsLocalControl(HANDLE hDevice,
  687. const GUID& AdapterGuid,
  688. LONG ioctl,
  689. PIOCTL_CVY_BUF in_bufp,
  690. PIOCTL_CVY_BUF out_bufp,
  691. DWORD vip)
  692. {
  693. BOOLEAN res;
  694. DWORD act;
  695. //
  696. // Add adapter GUID
  697. //
  698. IOCTL_LOCAL_HDR inBuf;
  699. IOCTL_LOCAL_HDR outBuf;
  700. WCHAR szGuid[128];
  701. StringFromGUID2(AdapterGuid, szGuid, sizeof(szGuid)/ sizeof(szGuid[0]));
  702. lstrcpy(inBuf.device_name, L"\\device\\");
  703. lstrcat(inBuf.device_name, szGuid);
  704. inBuf.ctrl = *in_bufp;
  705. switch (ioctl) {
  706. case IOCTL_CVY_CLUSTER_ON:
  707. case IOCTL_CVY_CLUSTER_OFF:
  708. break;
  709. case IOCTL_CVY_PORT_ON:
  710. case IOCTL_CVY_PORT_OFF:
  711. case IOCTL_CVY_PORT_SET:
  712. case IOCTL_CVY_PORT_DRAIN:
  713. {
  714. /* Set the port options. */
  715. inBuf.options.port.flags = 0;
  716. inBuf.options.port.virtual_ip_addr = vip;
  717. break;
  718. }
  719. case IOCTL_CVY_QUERY:
  720. break;
  721. case IOCTL_CVY_CLUSTER_DRAIN:
  722. case IOCTL_CVY_CLUSTER_SUSPEND:
  723. case IOCTL_CVY_CLUSTER_RESUME:
  724. break;
  725. case IOCTL_CVY_QUERY_STATE:
  726. break;
  727. default:
  728. break;
  729. }
  730. res = (BOOLEAN) DeviceIoControl (hDevice, ioctl, &inBuf, sizeof (inBuf),
  731. &outBuf, sizeof (outBuf), & act, NULL);
  732. *out_bufp = outBuf.ctrl;
  733. if (! res || act != sizeof (outBuf))
  734. return WLBS_IO_ERROR;
  735. return WLBS_OK;
  736. }
  737. //+----------------------------------------------------------------------------
  738. //
  739. // Function: NotifyDriverConfigChanges
  740. //
  741. // Description: Notify wlbs driver to pick up configuration changes from
  742. // registry
  743. //
  744. // Arguments: HANDLE hDeviceWlbs - The WLBS driver device handle
  745. // const GUID& - AdapterGuid Adapter guid
  746. //
  747. //
  748. // Returns: DWORD - Win32 Error code
  749. //
  750. // History: fengsun Created Header 2/3/00
  751. //
  752. //+----------------------------------------------------------------------------
  753. DWORD WINAPI NotifyDriverConfigChanges(HANDLE hDeviceWlbs, const GUID& AdapterGuid)
  754. {
  755. LONG status;
  756. IOCTL_CVY_BUF in_buf;
  757. IOCTL_CVY_BUF out_buf;
  758. status = WlbsLocalControl (hDeviceWlbs, AdapterGuid, IOCTL_CVY_RELOAD,
  759. & in_buf, & out_buf, 0);
  760. return ERROR_SUCCESS;
  761. }
  762. //+----------------------------------------------------------------------------
  763. //
  764. // Function: CWlbsControl::WlbsRemoteControl
  765. //
  766. // Description: Send a remote control packet
  767. //
  768. // Arguments: ONG ioctl -
  769. // PIOCTL_CVY_BUF pin_bufp -
  770. // PIOCTL_CVY_BUF pout_bufp -
  771. // PWLBS_RESPONSE pcvy_resp -
  772. // PDWORD nump -
  773. // DWORD trg_addr -
  774. // DWORD hst_addr
  775. //
  776. // Returns: DWORD -
  777. //
  778. // History: fengsun Created Header 1/25/00
  779. //
  780. //+----------------------------------------------------------------------------
  781. DWORD CWlbsControl::WlbsRemoteControl
  782. (
  783. LONG ioctl,
  784. PIOCTL_CVY_BUF pin_bufp,
  785. PIOCTL_CVY_BUF pout_bufp,
  786. PWLBS_RESPONSE pcvy_resp,
  787. PDWORD nump,
  788. DWORD trg_addr,
  789. DWORD hst_addr,
  790. DWORD vip
  791. )
  792. {
  793. INT ret;
  794. BOOLEAN responded [WLBS_MAX_HOSTS], heard;
  795. BOOL broadcast;
  796. DWORD mode, num_sends, num_recvs;
  797. SOCKET sock = INVALID_SOCKET;
  798. SOCKADDR_IN caddr, saddr;
  799. DWORD i, hosts;
  800. IOCTL_REMOTE_HDR rct_req;
  801. IOCTL_REMOTE_HDR rct_rep;
  802. PIOCTL_CVY_BUF in_bufp = & rct_req . ctrl;
  803. DWORD timeout;
  804. WORD port;
  805. DWORD dst_addr;
  806. DWORD passw;
  807. * in_bufp = * pin_bufp;
  808. timeout = m_def_timeout;
  809. port = m_def_port;
  810. dst_addr = m_def_dst_addr;
  811. passw = m_def_passw;
  812. // LOCK(m_lock);
  813. //
  814. // Find parameters for the cluster
  815. //
  816. for (i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  817. {
  818. if (m_cluster_params [i] . cluster == trg_addr)
  819. break;
  820. }
  821. if (i < WLBS_MAX_CLUSTERS)
  822. {
  823. timeout = m_cluster_params [i] . timeout;
  824. port = m_cluster_params [i] . port;
  825. dst_addr = m_cluster_params [i] . dest;
  826. passw = m_cluster_params [i] . passw;
  827. }
  828. CWlbsCluster* pCluster = GetClusterFromIp(trg_addr);
  829. /*
  830. if (pCluster)
  831. {
  832. //
  833. // Always uses password in registry for local cluster
  834. //
  835. passw = pCluster->GetPassword();
  836. }
  837. */
  838. // UNLOCK(m_lock);
  839. if (dst_addr == 0)
  840. dst_addr = trg_addr;
  841. rct_req . code = IOCTL_REMOTE_CODE;
  842. rct_req . version = CVY_VERSION_FULL;
  843. rct_req . id = GetTickCount ();
  844. rct_req . cluster = trg_addr;
  845. rct_req . host = hst_addr;
  846. rct_req . addr = m_dwSrcAddress;
  847. rct_req . password = passw;
  848. rct_req . ioctrl = ioctl;
  849. switch (ioctl) {
  850. case IOCTL_CVY_CLUSTER_ON:
  851. case IOCTL_CVY_CLUSTER_OFF:
  852. break;
  853. case IOCTL_CVY_PORT_ON:
  854. case IOCTL_CVY_PORT_OFF:
  855. case IOCTL_CVY_PORT_SET:
  856. case IOCTL_CVY_PORT_DRAIN:
  857. {
  858. /* Set the port options. */
  859. rct_req.options.port.flags = 0;
  860. rct_req.options.port.virtual_ip_addr = vip;
  861. break;
  862. }
  863. case IOCTL_CVY_QUERY:
  864. {
  865. BOOLEAN bIsMember = IsClusterMember(trg_addr);
  866. /* Reset the flags. */
  867. rct_req.options.query.flags = 0;
  868. /* Reset the hostname. */
  869. rct_req.options.query.hostname[0] = 0;
  870. /* If I am myself a member of the target cluster, then set the query cluster flags appropriately. */
  871. if (bIsMember)
  872. rct_req.options.query.flags |= IOCTL_OPTIONS_QUERY_CLUSTER_MEMBER;
  873. /* Request the hostname from each host. */
  874. rct_req.options.query.flags |= IOCTL_OPTIONS_QUERY_HOSTNAME;;
  875. break;
  876. }
  877. case IOCTL_CVY_CLUSTER_DRAIN:
  878. case IOCTL_CVY_CLUSTER_SUSPEND:
  879. case IOCTL_CVY_CLUSTER_RESUME:
  880. break;
  881. case IOCTL_CVY_QUERY_STATE:
  882. break;
  883. default:
  884. break;
  885. }
  886. /* now create socket */
  887. sock = socket (AF_INET, SOCK_DGRAM, 0);
  888. if (sock == INVALID_SOCKET)
  889. return WSAGetLastError();
  890. /* set socket to nonblocking mode */
  891. mode = 1;
  892. ret = ioctlsocket (sock, FIONBIO, & mode);
  893. if (ret == SOCKET_ERROR)
  894. {
  895. closesocket (sock);
  896. return WSAGetLastError();
  897. }
  898. /* bind client's address to socket */
  899. caddr . sin_family = AF_INET;
  900. caddr . sin_port = htons (0);
  901. BOOLEAN fBound = FALSE;
  902. if (pCluster)
  903. {
  904. //
  905. // For local cluster, always bind to the cluster IP.
  906. // Can not bind to the dedicated IP, which could be for a different NIC.
  907. //
  908. caddr . sin_addr . s_addr = trg_addr;
  909. if (bind (sock, (LPSOCKADDR) & caddr, sizeof (caddr)) != SOCKET_ERROR)
  910. {
  911. fBound = TRUE;
  912. }
  913. }
  914. if (!fBound)
  915. {
  916. //
  917. // For remote cluster, or fail to bind VIP/DIP, bind to the any IP
  918. //
  919. caddr . sin_addr . s_addr = htonl (INADDR_ANY);
  920. if (bind (sock, (LPSOCKADDR) & caddr, sizeof (caddr)) != SOCKET_ERROR)
  921. {
  922. fBound = TRUE;
  923. }
  924. }
  925. if (!fBound)
  926. {
  927. LOG_ERROR1("CWlbsControl::WlbsRemoteControl failed at bind %d", WSAGetLastError());
  928. closesocket (sock);
  929. return WSAGetLastError();
  930. }
  931. WORD wMyPort;
  932. wMyPort = QueryPortFromSocket(sock);
  933. //
  934. // The client is bound to the remote control server port
  935. // Let's get another port
  936. //
  937. if (wMyPort == htons (port))
  938. {
  939. closesocket (sock);
  940. sock = socket (AF_INET, SOCK_DGRAM, 0);
  941. if (sock == INVALID_SOCKET)
  942. return WSAGetLastError();
  943. /* set socket to nonblocking mode */
  944. mode = 1;
  945. ret = ioctlsocket (sock, FIONBIO, & mode);
  946. if (ret == SOCKET_ERROR)
  947. {
  948. closesocket (sock);
  949. return WSAGetLastError();
  950. }
  951. ret = bind (sock, (LPSOCKADDR) & caddr, sizeof (caddr));
  952. if (ret == SOCKET_ERROR)
  953. {
  954. closesocket (sock);
  955. return WSAGetLastError();
  956. }
  957. }
  958. /* setup server's address */
  959. saddr . sin_family = AF_INET;
  960. saddr . sin_port = htons (port);
  961. if ( pCluster ) // local cluster
  962. {
  963. /* enable sending broadcast on the socket */
  964. broadcast = TRUE;
  965. ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) & broadcast,
  966. sizeof (broadcast));
  967. if (ret == SOCKET_ERROR)
  968. {
  969. closesocket (sock);
  970. return WSAGetLastError();
  971. }
  972. saddr . sin_addr . s_addr = INADDR_BROADCAST;
  973. }
  974. else
  975. saddr . sin_addr . s_addr = dst_addr;
  976. for (i = 0; i < WLBS_MAX_HOSTS; i ++)
  977. responded [i] = FALSE;
  978. heard = FALSE;
  979. hosts = 0;
  980. for (num_sends = 0; num_sends < IOCTL_REMOTE_SEND_RETRIES; num_sends ++)
  981. {
  982. /* send remote control request message */
  983. ret = sendto (sock, (PCHAR) & rct_req, sizeof (rct_req), 0,
  984. (LPSOCKADDR) & saddr, sizeof (saddr));
  985. if (ret == SOCKET_ERROR)
  986. {
  987. LOG_ERROR1("CWlbsControl::WlbsRemoteControl failed at sendto %d", WSAGetLastError());
  988. //
  989. // Sendto could fail if the adapter is too busy. Allow retry
  990. //
  991. Sleep (timeout);
  992. continue;
  993. // closesocket (sock);
  994. // return WSAGetLastError();
  995. }
  996. if (ret != sizeof (rct_req))
  997. continue;
  998. for (num_recvs = 0; num_recvs < IOCTL_REMOTE_RECV_RETRIES; num_recvs ++)
  999. {
  1000. /* recv remote control reply message */
  1001. ret = recv (sock, (PCHAR) & rct_rep, sizeof (rct_rep), 0);
  1002. if (ret == SOCKET_ERROR)
  1003. {
  1004. if (WSAGetLastError() == WSAEWOULDBLOCK)
  1005. {
  1006. Sleep (timeout);
  1007. continue;
  1008. }
  1009. else if (WSAGetLastError() == WSAECONNRESET)
  1010. {
  1011. //
  1012. // Remote control is disabled
  1013. //
  1014. continue;
  1015. }
  1016. else
  1017. {
  1018. closesocket (sock);
  1019. return WSAGetLastError();
  1020. }
  1021. }
  1022. if (ret != sizeof (rct_rep))
  1023. {
  1024. Sleep (timeout);
  1025. continue;
  1026. }
  1027. if (rct_rep . cluster != trg_addr)
  1028. {
  1029. Sleep (timeout);
  1030. continue;
  1031. }
  1032. if (rct_rep . code != IOCTL_REMOTE_CODE)
  1033. {
  1034. Sleep (timeout);
  1035. continue;
  1036. }
  1037. if (rct_rep . id != rct_req . id)
  1038. {
  1039. Sleep (timeout);
  1040. continue;
  1041. }
  1042. if (rct_rep . host > WLBS_MAX_HOSTS || rct_rep . host == 0 )
  1043. {
  1044. Sleep (timeout);
  1045. continue;
  1046. }
  1047. if (! responded [rct_rep . host - 1])
  1048. {
  1049. if (hosts < WLBS_MAX_HOSTS)
  1050. {
  1051. pout_bufp [hosts] = rct_rep . ctrl;
  1052. if (hosts < * nump && pcvy_resp != NULL)
  1053. {
  1054. pcvy_resp [hosts] . id = rct_rep . host;
  1055. pcvy_resp [hosts] . address = rct_rep . addr;
  1056. if (rct_req . ioctrl == IOCTL_CVY_QUERY) {
  1057. pcvy_resp [hosts] . status =
  1058. MapStateFromDriverToApi (rct_rep . ctrl . data . query . state);
  1059. lstrcpy(pcvy_resp[hosts].hostname, rct_rep.options.query.hostname);
  1060. } else {
  1061. pcvy_resp [hosts] . status =
  1062. MapStateFromDriverToApi (rct_rep . ctrl . ret_code);
  1063. }
  1064. }
  1065. hosts ++;
  1066. }
  1067. }
  1068. responded [rct_rep . host - 1] = TRUE;
  1069. heard = TRUE;
  1070. if (hst_addr != WLBS_ALL_HOSTS)
  1071. {
  1072. * nump = hosts;
  1073. closesocket (sock);
  1074. return WLBS_OK;
  1075. }
  1076. }
  1077. }
  1078. * nump = hosts;
  1079. closesocket (sock);
  1080. if (! heard)
  1081. return WLBS_TIMEOUT;
  1082. return WLBS_OK;
  1083. }
  1084. //+----------------------------------------------------------------------------
  1085. //
  1086. // Function: CWlbsControl::WlbsQuery
  1087. //
  1088. // Description:
  1089. //
  1090. // Arguments: CWlbsCluster* pCluster -
  1091. // DWORD host -
  1092. // PWLBS_RESPONSE response -
  1093. // PDWORD num_hosts -
  1094. // PDWORD host_map -
  1095. // PVOID // reserved
  1096. //
  1097. // Returns: DWORD -
  1098. //
  1099. // History: fengsun Created Header 1/25/00
  1100. //
  1101. //+----------------------------------------------------------------------------
  1102. DWORD CWlbsControl::WlbsQuery
  1103. (
  1104. CWlbsCluster* pCluster,
  1105. DWORD host,
  1106. PWLBS_RESPONSE response,
  1107. PDWORD num_hosts,
  1108. PDWORD host_map,
  1109. PVOID // reserved
  1110. )
  1111. {
  1112. LONG ioctl = IOCTL_CVY_QUERY;
  1113. DWORD status;
  1114. IOCTL_CVY_BUF in_buf;
  1115. if (GetInitResult() == WLBS_INIT_ERROR)
  1116. return GetInitResult();
  1117. /* The following condition is to take care of the case when num_hosts is null
  1118. * and host_map contains some junk value. This could crash this function. */
  1119. if (num_hosts == NULL)
  1120. response = NULL;
  1121. else if (*num_hosts == 0)
  1122. response = NULL;
  1123. if (pCluster && IsLocalHost(pCluster, host))
  1124. {
  1125. IOCTL_CVY_BUF out_buf;
  1126. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1127. ioctl, & in_buf, & out_buf, 0);
  1128. if (status == WLBS_IO_ERROR)
  1129. return status;
  1130. if (host_map != NULL)
  1131. * host_map = out_buf . data . query . host_map;
  1132. if (response != NULL)
  1133. {
  1134. response [0] . id = out_buf . data . query . host_id;
  1135. response [0] . address = 0;
  1136. response [0] . status = MapStateFromDriverToApi (out_buf . data . query . state);
  1137. }
  1138. if (num_hosts != NULL)
  1139. * num_hosts = 1;
  1140. status = MapStateFromDriverToApi (out_buf . data . query . state);
  1141. }
  1142. else
  1143. {
  1144. status = RemoteQuery(pCluster->GetClusterIp(),
  1145. host, response, num_hosts, host_map);
  1146. }
  1147. return status;
  1148. }
  1149. //+----------------------------------------------------------------------------
  1150. //
  1151. // Function: CWlbsControl::WlbsQuery
  1152. //
  1153. // Description:
  1154. //
  1155. // Arguments: WORD cluster -
  1156. // DWORD host -
  1157. // PWLBS_RESPONSE response -
  1158. // PDWORD num_hosts -
  1159. // PDWORD host_map -
  1160. // PVOID // reserved
  1161. //
  1162. // Returns: DWORD -
  1163. //
  1164. // History: fengsun Created Header 1/25/00
  1165. //
  1166. //+----------------------------------------------------------------------------
  1167. DWORD CWlbsControl::WlbsQuery
  1168. (
  1169. DWORD cluster,
  1170. DWORD host,
  1171. PWLBS_RESPONSE response,
  1172. PDWORD num_hosts,
  1173. PDWORD host_map,
  1174. PVOID // reserved
  1175. )
  1176. {
  1177. DWORD ret;
  1178. TRACE_INFO("> WlbsQuery: cluster=0x%lx, host=0x%lx", cluster, host);
  1179. if (GetInitResult() == WLBS_INIT_ERROR)
  1180. {
  1181. ret = GetInitResult();
  1182. goto end;
  1183. }
  1184. if (cluster == WLBS_LOCAL_CLUSTER && (GetInitResult() == WLBS_REMOTE_ONLY))
  1185. {
  1186. ret = GetInitResult();
  1187. goto end;
  1188. }
  1189. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1190. if (pCluster == NULL)
  1191. {
  1192. ret = RemoteQuery(cluster, host, response, num_hosts, host_map);
  1193. goto end;
  1194. }
  1195. else
  1196. {
  1197. ret = WlbsQuery(pCluster, host, response, num_hosts, host_map, NULL);
  1198. goto end;
  1199. }
  1200. end:
  1201. TRACE_INFO("< WlbsQuery: return %d", ret);
  1202. return ret;
  1203. }
  1204. //+----------------------------------------------------------------------------
  1205. //
  1206. // Function: CWlbsControl::RemoteQuery
  1207. //
  1208. // Description:
  1209. //
  1210. // Arguments: DWORD cluster -
  1211. // DWORD host -
  1212. // PWLBS_RESPONSE response -
  1213. // PDWORD num_hosts -
  1214. // PDWORD host_map -
  1215. //
  1216. // Returns: DWORD -
  1217. //
  1218. // History: fengsun Created Header 1/25/00
  1219. //
  1220. //+----------------------------------------------------------------------------
  1221. DWORD CWlbsControl::RemoteQuery
  1222. (
  1223. DWORD cluster,
  1224. DWORD host,
  1225. PWLBS_RESPONSE response,
  1226. PDWORD num_hosts,
  1227. PDWORD host_map
  1228. )
  1229. {
  1230. LONG ioctl = IOCTL_CVY_QUERY;
  1231. DWORD status;
  1232. IOCTL_CVY_BUF in_buf;
  1233. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1234. DWORD hosts;
  1235. DWORD hmap = 0;
  1236. DWORD active;
  1237. DWORD i;
  1238. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1239. return GetInitResult();
  1240. if (num_hosts != NULL)
  1241. hosts = * num_hosts;
  1242. else
  1243. hosts = 0;
  1244. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1245. cluster, host, 0);
  1246. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1247. {
  1248. if (num_hosts != NULL)
  1249. * num_hosts = 0;
  1250. return status;
  1251. }
  1252. if (host == WLBS_ALL_HOSTS)
  1253. {
  1254. for (status = WLBS_STOPPED, active = 0, i = 0; i < hosts; i ++)
  1255. {
  1256. switch (MapStateFromDriverToApi (out_buf [i] . data . query . state))
  1257. {
  1258. case WLBS_SUSPENDED:
  1259. if (status == WLBS_STOPPED)
  1260. status = WLBS_SUSPENDED;
  1261. break;
  1262. case WLBS_CONVERGING:
  1263. if (status != WLBS_BAD_PASSW)
  1264. status = WLBS_CONVERGING;
  1265. break;
  1266. case WLBS_DRAINING:
  1267. if (status == WLBS_STOPPED)
  1268. status = WLBS_DRAINING;
  1269. break;
  1270. case WLBS_CONVERGED:
  1271. if (status != WLBS_CONVERGING && status != WLBS_BAD_PASSW)
  1272. status = WLBS_CONVERGED;
  1273. hmap = out_buf [i] . data . query . host_map;
  1274. active ++;
  1275. break;
  1276. case WLBS_BAD_PASSW:
  1277. status = WLBS_BAD_PASSW;
  1278. break;
  1279. case WLBS_DEFAULT:
  1280. if (status != WLBS_CONVERGING && status != WLBS_BAD_PASSW)
  1281. status = WLBS_CONVERGED;
  1282. hmap = out_buf [i] . data . query . host_map;
  1283. active ++;
  1284. break;
  1285. case WLBS_STOPPED:
  1286. default:
  1287. break;
  1288. }
  1289. }
  1290. if (status == WLBS_CONVERGED)
  1291. status = active;
  1292. }
  1293. else
  1294. {
  1295. status = MapStateFromDriverToApi (out_buf [0] . data . query . state);
  1296. hmap = out_buf [0] . data . query . host_map;
  1297. }
  1298. if (host_map != NULL)
  1299. * host_map = hmap;
  1300. if (num_hosts != NULL)
  1301. * num_hosts = hosts;
  1302. return status;
  1303. }
  1304. //+----------------------------------------------------------------------------
  1305. //
  1306. // Function: CWlbsControl::WlbsSuspend
  1307. //
  1308. // Description:
  1309. //
  1310. // Arguments: WORD cluster -
  1311. // DWORD host -
  1312. // PWLBS_RESPONSE response -
  1313. // PDWORD num_hosts
  1314. //
  1315. // Returns: DWORD -
  1316. //
  1317. // History: fengsun Created Header 1/25/00
  1318. //
  1319. //+----------------------------------------------------------------------------
  1320. DWORD CWlbsControl::WlbsSuspend
  1321. (
  1322. DWORD cluster,
  1323. DWORD host,
  1324. PWLBS_RESPONSE response,
  1325. PDWORD num_hosts
  1326. )
  1327. {
  1328. LONG ioctl = IOCTL_CVY_CLUSTER_SUSPEND;
  1329. DWORD status;
  1330. IOCTL_CVY_BUF in_buf;
  1331. if (GetInitResult() == WLBS_INIT_ERROR)
  1332. return GetInitResult();
  1333. if (num_hosts == NULL)
  1334. response = NULL;
  1335. else if (*num_hosts == 0)
  1336. response = NULL;
  1337. CWlbsCluster* pCluster= GetClusterFromIpOrIndex(cluster);
  1338. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  1339. return GetInitResult();
  1340. if (pCluster && IsLocalHost(pCluster, host))
  1341. {
  1342. IOCTL_CVY_BUF out_buf;
  1343. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1344. ioctl, & in_buf, & out_buf, 0);
  1345. if (status == WLBS_IO_ERROR)
  1346. return status;
  1347. if (num_hosts != NULL)
  1348. * num_hosts = 0;
  1349. status = MapStateFromDriverToApi (out_buf . ret_code);
  1350. }
  1351. else
  1352. {
  1353. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1354. DWORD hosts;
  1355. DWORD i;
  1356. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1357. return GetInitResult();
  1358. if (num_hosts != NULL)
  1359. hosts = * num_hosts;
  1360. else
  1361. hosts = 0;
  1362. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1363. cluster, host, 0);
  1364. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1365. return status;
  1366. if (host == WLBS_ALL_HOSTS)
  1367. {
  1368. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  1369. {
  1370. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1371. {
  1372. case WLBS_BAD_PASSW:
  1373. status = WLBS_BAD_PASSW;
  1374. break;
  1375. case WLBS_OK:
  1376. case WLBS_ALREADY:
  1377. case WLBS_STOPPED:
  1378. case WLBS_DRAIN_STOP:
  1379. default:
  1380. break;
  1381. }
  1382. }
  1383. }
  1384. else
  1385. {
  1386. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1387. }
  1388. if (num_hosts != NULL)
  1389. * num_hosts = hosts;
  1390. }
  1391. return status;
  1392. }
  1393. //+----------------------------------------------------------------------------
  1394. //
  1395. // Function: CWlbsControl::WlbsResume
  1396. //
  1397. // Description:
  1398. //
  1399. // Arguments: WORD cluster -
  1400. // DWORD host -
  1401. // PWLBS_RESPONSE response -
  1402. // PDWORD num_hosts
  1403. //
  1404. // Returns: DWORD -
  1405. //
  1406. // History: fengsun Created Header 1/25/00
  1407. //
  1408. //+----------------------------------------------------------------------------
  1409. DWORD CWlbsControl::WlbsResume
  1410. (
  1411. DWORD cluster,
  1412. DWORD host,
  1413. PWLBS_RESPONSE response,
  1414. PDWORD num_hosts
  1415. )
  1416. {
  1417. LONG ioctl = IOCTL_CVY_CLUSTER_RESUME;
  1418. DWORD status;
  1419. IOCTL_CVY_BUF in_buf;
  1420. if (GetInitResult() == WLBS_INIT_ERROR)
  1421. return GetInitResult();
  1422. if (num_hosts == NULL)
  1423. response = NULL;
  1424. else if (*num_hosts == 0)
  1425. response = NULL;
  1426. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1427. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  1428. return GetInitResult();
  1429. if (pCluster && IsLocalHost(pCluster, host))
  1430. {
  1431. IOCTL_CVY_BUF out_buf;
  1432. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1433. ioctl, & in_buf, & out_buf, 0);
  1434. if (status == WLBS_IO_ERROR)
  1435. return status;
  1436. if (num_hosts != NULL)
  1437. * num_hosts = 0;
  1438. status = MapStateFromDriverToApi (out_buf . ret_code);
  1439. }
  1440. else
  1441. {
  1442. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1443. DWORD hosts;
  1444. DWORD i;
  1445. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1446. return GetInitResult();
  1447. if (num_hosts != NULL)
  1448. hosts = * num_hosts;
  1449. else
  1450. hosts = 0;
  1451. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1452. cluster, host, 0);
  1453. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1454. return status;
  1455. if (host == WLBS_ALL_HOSTS)
  1456. {
  1457. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  1458. {
  1459. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1460. {
  1461. case WLBS_BAD_PASSW:
  1462. status = WLBS_BAD_PASSW;
  1463. break;
  1464. case WLBS_OK:
  1465. case WLBS_ALREADY:
  1466. default:
  1467. break;
  1468. }
  1469. }
  1470. }
  1471. else
  1472. {
  1473. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1474. }
  1475. if (num_hosts != NULL)
  1476. * num_hosts = hosts;
  1477. }
  1478. return status;
  1479. }
  1480. //+----------------------------------------------------------------------------
  1481. //
  1482. // Function: CWlbsControl::WlbsStart
  1483. //
  1484. // Description:
  1485. //
  1486. // Arguments: WORD cluster -
  1487. // DWORD host -
  1488. // PWLBS_RESPONSE response -
  1489. // PDWORD num_hosts
  1490. //
  1491. // Returns: DWORD -
  1492. //
  1493. // History: fengsun Created Header 1/25/00
  1494. //
  1495. //+----------------------------------------------------------------------------
  1496. DWORD CWlbsControl::WlbsStart
  1497. (
  1498. DWORD cluster,
  1499. DWORD host,
  1500. PWLBS_RESPONSE response,
  1501. PDWORD num_hosts
  1502. )
  1503. {
  1504. LONG ioctl = IOCTL_CVY_CLUSTER_ON;
  1505. DWORD status;
  1506. IOCTL_CVY_BUF in_buf;
  1507. if (GetInitResult() == WLBS_INIT_ERROR)
  1508. return GetInitResult();
  1509. if (num_hosts == NULL)
  1510. response = NULL;
  1511. else if (*num_hosts == 0)
  1512. response = NULL;
  1513. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1514. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  1515. return GetInitResult();
  1516. if (pCluster && IsLocalHost(pCluster, host))
  1517. {
  1518. IOCTL_CVY_BUF out_buf;
  1519. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1520. ioctl, & in_buf, & out_buf, 0);
  1521. if (status == WLBS_IO_ERROR)
  1522. return status;
  1523. if (num_hosts != NULL)
  1524. * num_hosts = 0;
  1525. status = MapStateFromDriverToApi (out_buf . ret_code);
  1526. }
  1527. else
  1528. {
  1529. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1530. DWORD hosts;
  1531. DWORD i;
  1532. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1533. return GetInitResult();
  1534. if (num_hosts != NULL)
  1535. hosts = * num_hosts;
  1536. else
  1537. hosts = 0;
  1538. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1539. cluster, host, 0);
  1540. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1541. return status;
  1542. if (host == WLBS_ALL_HOSTS)
  1543. {
  1544. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  1545. {
  1546. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1547. {
  1548. case WLBS_BAD_PARAMS:
  1549. if (status != WLBS_BAD_PASSW)
  1550. status = WLBS_BAD_PARAMS;
  1551. break;
  1552. case WLBS_BAD_PASSW:
  1553. status = WLBS_BAD_PASSW;
  1554. break;
  1555. case WLBS_SUSPENDED:
  1556. if (status != WLBS_BAD_PASSW && status != WLBS_BAD_PARAMS)
  1557. status = WLBS_SUSPENDED;
  1558. break;
  1559. case WLBS_OK:
  1560. case WLBS_ALREADY:
  1561. case WLBS_DRAIN_STOP:
  1562. break;
  1563. default:
  1564. break;
  1565. }
  1566. }
  1567. }
  1568. else
  1569. {
  1570. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1571. }
  1572. if (num_hosts != NULL)
  1573. * num_hosts = hosts;
  1574. }
  1575. return status;
  1576. }
  1577. //+----------------------------------------------------------------------------
  1578. //
  1579. // Function: CWlbsControl::WlbsStop
  1580. //
  1581. // Description:
  1582. //
  1583. // Arguments: WORD cluster -
  1584. // DWORD host -
  1585. // PWLBS_RESPONSE response -
  1586. // PDWORD num_hosts
  1587. //
  1588. // Returns: DWORD -
  1589. //
  1590. // History: fengsun Created Header 1/25/00
  1591. //
  1592. //+----------------------------------------------------------------------------
  1593. DWORD CWlbsControl::WlbsStop
  1594. (
  1595. DWORD cluster,
  1596. DWORD host,
  1597. PWLBS_RESPONSE response,
  1598. PDWORD num_hosts
  1599. )
  1600. {
  1601. LONG ioctl = IOCTL_CVY_CLUSTER_OFF;
  1602. DWORD status;
  1603. IOCTL_CVY_BUF in_buf;
  1604. if (GetInitResult() == WLBS_INIT_ERROR)
  1605. return GetInitResult();
  1606. if (num_hosts == NULL)
  1607. response = NULL;
  1608. else if (*num_hosts == 0)
  1609. response = NULL;
  1610. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1611. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  1612. return GetInitResult();
  1613. if (pCluster && IsLocalHost(pCluster, host))
  1614. {
  1615. IOCTL_CVY_BUF out_buf;
  1616. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1617. ioctl, & in_buf, & out_buf, 0);
  1618. if (status == WLBS_IO_ERROR)
  1619. return status;
  1620. if (num_hosts != NULL)
  1621. * num_hosts = 0;
  1622. status = MapStateFromDriverToApi (out_buf . ret_code);
  1623. }
  1624. else
  1625. {
  1626. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1627. DWORD hosts;
  1628. DWORD i;
  1629. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1630. return GetInitResult();
  1631. if (num_hosts != NULL)
  1632. hosts = * num_hosts;
  1633. else
  1634. hosts = 0;
  1635. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1636. cluster, host, 0);
  1637. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1638. return status;
  1639. if (host == WLBS_ALL_HOSTS)
  1640. {
  1641. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  1642. {
  1643. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1644. {
  1645. case WLBS_BAD_PASSW:
  1646. status = WLBS_BAD_PASSW;
  1647. break;
  1648. case WLBS_SUSPENDED:
  1649. if (status != WLBS_BAD_PASSW)
  1650. status = WLBS_SUSPENDED;
  1651. break;
  1652. case WLBS_OK:
  1653. case WLBS_ALREADY:
  1654. case WLBS_DRAIN_STOP:
  1655. default:
  1656. break;
  1657. }
  1658. }
  1659. }
  1660. else
  1661. {
  1662. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1663. }
  1664. if (num_hosts != NULL)
  1665. * num_hosts = hosts;
  1666. }
  1667. return status;
  1668. }
  1669. //+----------------------------------------------------------------------------
  1670. //
  1671. // Function: CWlbsControl::WlbsDrainStop
  1672. //
  1673. // Description:
  1674. //
  1675. // Arguments: WORD cluster -
  1676. // DWORD host -
  1677. // PWLBS_RESPONSE response -
  1678. // PDWORD num_hosts
  1679. //
  1680. // Returns: DWORD -
  1681. //
  1682. // History: fengsun Created Header 1/25/00
  1683. //
  1684. //+----------------------------------------------------------------------------
  1685. DWORD CWlbsControl::WlbsDrainStop
  1686. (
  1687. DWORD cluster,
  1688. DWORD host,
  1689. PWLBS_RESPONSE response,
  1690. PDWORD num_hosts
  1691. )
  1692. {
  1693. LONG ioctl = IOCTL_CVY_CLUSTER_DRAIN;
  1694. DWORD status;
  1695. IOCTL_CVY_BUF in_buf;
  1696. if (GetInitResult() == WLBS_INIT_ERROR)
  1697. return GetInitResult();
  1698. if (num_hosts == NULL)
  1699. response = NULL;
  1700. else if (*num_hosts == 0)
  1701. response = NULL;
  1702. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1703. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  1704. return GetInitResult();
  1705. if (pCluster && IsLocalHost(pCluster, host))
  1706. {
  1707. IOCTL_CVY_BUF out_buf;
  1708. status = WlbsLocalControl (m_hdl,pCluster->GetAdapterGuid(),
  1709. ioctl, & in_buf, & out_buf, 0);
  1710. if (status == WLBS_IO_ERROR)
  1711. return status;
  1712. if (num_hosts != NULL)
  1713. * num_hosts = 0;
  1714. status = MapStateFromDriverToApi (out_buf . ret_code);
  1715. }
  1716. else
  1717. {
  1718. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1719. DWORD hosts;
  1720. DWORD i;
  1721. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1722. return GetInitResult();
  1723. if (num_hosts != NULL)
  1724. hosts = * num_hosts;
  1725. else
  1726. hosts = 0;
  1727. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1728. cluster, host, 0);
  1729. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1730. return status;
  1731. if (host == WLBS_ALL_HOSTS)
  1732. {
  1733. for (status = WLBS_STOPPED, i = 0; i < hosts; i ++)
  1734. {
  1735. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1736. {
  1737. case WLBS_BAD_PASSW:
  1738. status = WLBS_BAD_PASSW;
  1739. break;
  1740. case WLBS_SUSPENDED:
  1741. if (status != WLBS_BAD_PASSW)
  1742. status = WLBS_SUSPENDED;
  1743. break;
  1744. case WLBS_OK:
  1745. case WLBS_ALREADY:
  1746. if (status != WLBS_BAD_PASSW && status != WLBS_SUSPENDED)
  1747. status = WLBS_OK;
  1748. case WLBS_STOPPED:
  1749. default:
  1750. break;
  1751. }
  1752. }
  1753. }
  1754. else
  1755. {
  1756. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1757. }
  1758. if (num_hosts != NULL)
  1759. * num_hosts = hosts;
  1760. }
  1761. return status;
  1762. }
  1763. //+----------------------------------------------------------------------------
  1764. //
  1765. // Function: CWlbsControl::WlbsEnable
  1766. //
  1767. // Description:
  1768. //
  1769. // Arguments: WORD cluster -
  1770. // DWORD host -
  1771. // PWLBS_RESPONSE response -
  1772. // PDWORD num_hosts -
  1773. // DWORD port
  1774. //
  1775. // Returns: DWORD -
  1776. //
  1777. // History: fengsun Created Header 1/25/00
  1778. //
  1779. //+----------------------------------------------------------------------------
  1780. DWORD CWlbsControl::WlbsEnable
  1781. (
  1782. DWORD cluster,
  1783. DWORD host,
  1784. PWLBS_RESPONSE response,
  1785. PDWORD num_hosts,
  1786. DWORD vip,
  1787. DWORD port
  1788. )
  1789. {
  1790. LONG ioctl = IOCTL_CVY_PORT_ON;
  1791. DWORD status;
  1792. IOCTL_CVY_BUF in_buf;
  1793. if (GetInitResult() == WLBS_INIT_ERROR)
  1794. return GetInitResult();
  1795. if (num_hosts == NULL)
  1796. response = NULL;
  1797. else if (*num_hosts == 0)
  1798. response = NULL;
  1799. in_buf . data . port . num = port;
  1800. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1801. if (pCluster&& (GetInitResult() == WLBS_REMOTE_ONLY))
  1802. return GetInitResult();
  1803. if (pCluster && IsLocalHost(pCluster, host))
  1804. {
  1805. IOCTL_CVY_BUF out_buf;
  1806. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1807. ioctl, & in_buf, & out_buf, vip);
  1808. if (status == WLBS_IO_ERROR)
  1809. return status;
  1810. if (num_hosts != NULL)
  1811. * num_hosts = 0;
  1812. status = MapStateFromDriverToApi (out_buf . ret_code);
  1813. }
  1814. else
  1815. {
  1816. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1817. DWORD hosts;
  1818. DWORD i;
  1819. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1820. return GetInitResult();
  1821. if (num_hosts != NULL)
  1822. hosts = * num_hosts;
  1823. else
  1824. hosts = 0;
  1825. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1826. cluster, host, vip);
  1827. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1828. return status;
  1829. if (host == WLBS_ALL_HOSTS)
  1830. {
  1831. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  1832. {
  1833. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1834. {
  1835. case WLBS_BAD_PASSW:
  1836. status = WLBS_BAD_PASSW;
  1837. break;
  1838. case WLBS_NOT_FOUND:
  1839. if (status != WLBS_BAD_PASSW)
  1840. status = WLBS_NOT_FOUND;
  1841. break;
  1842. case WLBS_SUSPENDED:
  1843. if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND)
  1844. status = WLBS_SUSPENDED;
  1845. break;
  1846. case WLBS_OK:
  1847. case WLBS_ALREADY:
  1848. case WLBS_STOPPED:
  1849. case WLBS_DRAINING:
  1850. default:
  1851. break;
  1852. }
  1853. }
  1854. }
  1855. else
  1856. {
  1857. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1858. }
  1859. if (num_hosts != NULL)
  1860. * num_hosts = hosts;
  1861. }
  1862. return status;
  1863. }
  1864. //+----------------------------------------------------------------------------
  1865. //
  1866. // Function: CWlbsControl::WlbsDisable
  1867. //
  1868. // Description:
  1869. //
  1870. // Arguments: WORD cluster -
  1871. // DWORD host -
  1872. // PWLBS_RESPONSE response -
  1873. // PDWORD num_hosts -
  1874. // DWORD port
  1875. //
  1876. // Returns: DWORD -
  1877. //
  1878. // History: fengsun Created Header 1/25/00
  1879. //
  1880. //+----------------------------------------------------------------------------
  1881. DWORD CWlbsControl::WlbsDisable
  1882. (
  1883. DWORD cluster,
  1884. DWORD host,
  1885. PWLBS_RESPONSE response,
  1886. PDWORD num_hosts,
  1887. DWORD vip,
  1888. DWORD port
  1889. )
  1890. {
  1891. LONG ioctl = IOCTL_CVY_PORT_OFF;
  1892. DWORD status;
  1893. IOCTL_CVY_BUF in_buf;
  1894. if (GetInitResult() == WLBS_INIT_ERROR)
  1895. return GetInitResult();
  1896. if (num_hosts == NULL)
  1897. response = NULL;
  1898. else if (*num_hosts == 0)
  1899. response = NULL;
  1900. in_buf . data . port . num = port;
  1901. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  1902. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  1903. return GetInitResult();
  1904. if (pCluster && IsLocalHost(pCluster, host))
  1905. {
  1906. IOCTL_CVY_BUF out_buf;
  1907. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  1908. ioctl, & in_buf, & out_buf, vip);
  1909. if (status == WLBS_IO_ERROR)
  1910. return status;
  1911. if (num_hosts != NULL)
  1912. * num_hosts = 0;
  1913. status = MapStateFromDriverToApi (out_buf . ret_code);
  1914. }
  1915. else
  1916. {
  1917. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  1918. DWORD hosts;
  1919. DWORD i;
  1920. if (GetInitResult() == WLBS_LOCAL_ONLY)
  1921. return GetInitResult();
  1922. if (num_hosts != NULL)
  1923. hosts = * num_hosts;
  1924. else
  1925. hosts = 0;
  1926. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  1927. cluster, host, vip);
  1928. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  1929. return status;
  1930. if (host == WLBS_ALL_HOSTS)
  1931. {
  1932. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  1933. {
  1934. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  1935. {
  1936. case WLBS_BAD_PASSW:
  1937. status = WLBS_BAD_PASSW;
  1938. break;
  1939. case WLBS_NOT_FOUND:
  1940. if (status != WLBS_BAD_PASSW)
  1941. status = WLBS_NOT_FOUND;
  1942. break;
  1943. case WLBS_SUSPENDED:
  1944. if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND)
  1945. status = WLBS_SUSPENDED;
  1946. break;
  1947. case WLBS_OK:
  1948. case WLBS_ALREADY:
  1949. case WLBS_STOPPED:
  1950. case WLBS_DRAINING:
  1951. default:
  1952. break;
  1953. }
  1954. }
  1955. }
  1956. else
  1957. {
  1958. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  1959. }
  1960. if (num_hosts != NULL)
  1961. * num_hosts = hosts;
  1962. }
  1963. return status;
  1964. }
  1965. //+----------------------------------------------------------------------------
  1966. //
  1967. // Function: CWlbsControl::WlbsDrain
  1968. //
  1969. // Description:
  1970. //
  1971. // Arguments: WORD cluster -
  1972. // DWORD host -
  1973. // PWLBS_RESPONSE response -
  1974. // PDWORD num_hosts -
  1975. // DWORD port
  1976. //
  1977. // Returns: DWORD -
  1978. //
  1979. // History: fengsun Created Header 1/25/00
  1980. //
  1981. //+----------------------------------------------------------------------------
  1982. DWORD CWlbsControl::WlbsDrain
  1983. (
  1984. DWORD cluster,
  1985. DWORD host,
  1986. PWLBS_RESPONSE response,
  1987. PDWORD num_hosts,
  1988. DWORD vip,
  1989. DWORD port
  1990. )
  1991. {
  1992. LONG ioctl = IOCTL_CVY_PORT_DRAIN;
  1993. DWORD status;
  1994. IOCTL_CVY_BUF in_buf;
  1995. if (GetInitResult() == WLBS_INIT_ERROR)
  1996. return GetInitResult();
  1997. if (num_hosts == NULL)
  1998. response = NULL;
  1999. else if (*num_hosts == 0)
  2000. response = NULL;
  2001. in_buf . data . port . num = port;
  2002. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  2003. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  2004. return GetInitResult();
  2005. if (pCluster && IsLocalHost(pCluster, host))
  2006. {
  2007. IOCTL_CVY_BUF out_buf;
  2008. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  2009. ioctl, & in_buf, & out_buf, vip);
  2010. if (status == WLBS_IO_ERROR)
  2011. return status;
  2012. if (num_hosts != NULL)
  2013. * num_hosts = 0;
  2014. status = MapStateFromDriverToApi (out_buf . ret_code);
  2015. }
  2016. else
  2017. {
  2018. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  2019. DWORD hosts;
  2020. DWORD i;
  2021. if (GetInitResult() == WLBS_LOCAL_ONLY)
  2022. return GetInitResult();
  2023. if (num_hosts != NULL)
  2024. hosts = * num_hosts;
  2025. else
  2026. hosts = 0;
  2027. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  2028. cluster, host, vip);
  2029. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  2030. return status;
  2031. if (host == WLBS_ALL_HOSTS)
  2032. {
  2033. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  2034. {
  2035. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  2036. {
  2037. case WLBS_BAD_PASSW:
  2038. status = WLBS_BAD_PASSW;
  2039. break;
  2040. case WLBS_NOT_FOUND:
  2041. if (status != WLBS_BAD_PASSW)
  2042. status = WLBS_NOT_FOUND;
  2043. break;
  2044. case WLBS_SUSPENDED:
  2045. if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND)
  2046. status = WLBS_SUSPENDED;
  2047. break;
  2048. case WLBS_OK:
  2049. case WLBS_ALREADY:
  2050. case WLBS_STOPPED:
  2051. case WLBS_DRAINING:
  2052. default:
  2053. break;
  2054. }
  2055. }
  2056. }
  2057. else
  2058. {
  2059. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  2060. }
  2061. if (num_hosts != NULL)
  2062. * num_hosts = hosts;
  2063. }
  2064. return status;
  2065. }
  2066. //+----------------------------------------------------------------------------
  2067. //
  2068. // Function: CWlbsControl::WlbsAdjust
  2069. //
  2070. // Description:
  2071. //
  2072. // Arguments: WORD cluster -
  2073. // DWORD host -
  2074. // PWLBS_RESPONSE response -
  2075. // PDWORD num_hosts -
  2076. // DWORD port -
  2077. // DWORD value
  2078. //
  2079. // Returns: DWORD -
  2080. //
  2081. // History: fengsun Created Header 1/25/00
  2082. //
  2083. //+----------------------------------------------------------------------------
  2084. DWORD CWlbsControl::WlbsAdjust
  2085. (
  2086. DWORD cluster,
  2087. DWORD host,
  2088. PWLBS_RESPONSE response,
  2089. PDWORD num_hosts,
  2090. DWORD port,
  2091. DWORD value
  2092. )
  2093. {
  2094. LONG ioctl = IOCTL_CVY_PORT_SET;
  2095. DWORD status;
  2096. IOCTL_CVY_BUF in_buf;
  2097. if (GetInitResult() == WLBS_INIT_ERROR)
  2098. return GetInitResult();
  2099. in_buf . data . port . num = port;
  2100. in_buf . data . port . load = value;
  2101. CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster);
  2102. if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY))
  2103. return GetInitResult();
  2104. if (pCluster && IsLocalHost(pCluster, host))
  2105. {
  2106. IOCTL_CVY_BUF out_buf;
  2107. status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(),
  2108. ioctl, & in_buf, & out_buf, 0);
  2109. if (status == WLBS_IO_ERROR)
  2110. return status;
  2111. if (num_hosts != NULL)
  2112. * num_hosts = 0;
  2113. status = MapStateFromDriverToApi (out_buf . ret_code);
  2114. }
  2115. else
  2116. {
  2117. IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS];
  2118. DWORD hosts;
  2119. DWORD i;
  2120. if (GetInitResult() == WLBS_LOCAL_ONLY)
  2121. return GetInitResult();
  2122. if (num_hosts != NULL)
  2123. hosts = * num_hosts;
  2124. else
  2125. hosts = 0;
  2126. status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts,
  2127. cluster, host, 0);
  2128. if (status >= WSABASEERR || status == WLBS_TIMEOUT)
  2129. return status;
  2130. if (host == WLBS_ALL_HOSTS)
  2131. {
  2132. for (status = WLBS_OK, i = 0; i < hosts; i ++)
  2133. {
  2134. switch (MapStateFromDriverToApi (out_buf [i] . ret_code))
  2135. {
  2136. case WLBS_BAD_PASSW:
  2137. status = WLBS_BAD_PASSW;
  2138. break;
  2139. case WLBS_NOT_FOUND:
  2140. if (status != WLBS_BAD_PASSW)
  2141. status = WLBS_NOT_FOUND;
  2142. break;
  2143. case WLBS_SUSPENDED:
  2144. if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND)
  2145. status = WLBS_SUSPENDED;
  2146. break;
  2147. case WLBS_OK:
  2148. case WLBS_ALREADY:
  2149. case WLBS_STOPPED:
  2150. case WLBS_DRAINING:
  2151. default:
  2152. break;
  2153. }
  2154. }
  2155. }
  2156. else
  2157. {
  2158. status = MapStateFromDriverToApi (out_buf [0] . ret_code);
  2159. }
  2160. if (num_hosts != NULL)
  2161. * num_hosts = hosts;
  2162. }
  2163. return status;
  2164. }
  2165. //+----------------------------------------------------------------------------
  2166. //
  2167. // Function: CWlbsControl::WlbsPortSet
  2168. //
  2169. // Description:
  2170. //
  2171. // Arguments: DWORD cluster -
  2172. // WORD port -
  2173. //
  2174. // Returns: Nothing
  2175. //
  2176. // History: fengsun Created Header 1/25/00
  2177. //
  2178. //+----------------------------------------------------------------------------
  2179. VOID CWlbsControl::WlbsPortSet(DWORD cluster, WORD port)
  2180. {
  2181. DWORD i;
  2182. DWORD j;
  2183. WORD rct_port;
  2184. // LOCK(global_info.lock);
  2185. if (port == 0)
  2186. rct_port = CVY_DEF_RCT_PORT;
  2187. else
  2188. rct_port = port;
  2189. if (cluster == WLBS_ALL_CLUSTERS)
  2190. {
  2191. /* when all clusters are targeted - change the default and go through
  2192. the entire parameter table setting new values */
  2193. m_def_port = rct_port;
  2194. for (i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  2195. m_cluster_params [i] . port = rct_port;
  2196. }
  2197. else
  2198. {
  2199. for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++)
  2200. {
  2201. /* mark an empty slot in case we will have to enter a new value */
  2202. if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0)
  2203. j = i;
  2204. if (m_cluster_params [i] . cluster == cluster)
  2205. {
  2206. m_cluster_params [i] . port = rct_port;
  2207. break;
  2208. }
  2209. }
  2210. /* if we did not locate specified cluster in the table and there is an
  2211. empty slot - enter new cluster info in the table */
  2212. if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS)
  2213. {
  2214. m_cluster_params [j] . cluster = cluster;
  2215. m_cluster_params [j] . port = rct_port;
  2216. }
  2217. }
  2218. // UNLOCK(global_info.lock);
  2219. }
  2220. //+----------------------------------------------------------------------------
  2221. //
  2222. // Function: CWlbsControl::WlbsPasswordSet
  2223. //
  2224. // Description:
  2225. //
  2226. // Arguments: WORD cluster -
  2227. // PTCHAR password
  2228. //
  2229. // Returns: Nothing
  2230. //
  2231. // History: fengsun Created Header 1/25/00
  2232. //
  2233. //+----------------------------------------------------------------------------
  2234. VOID CWlbsControl::WlbsPasswordSet
  2235. (
  2236. DWORD cluster,
  2237. const WCHAR* password
  2238. )
  2239. {
  2240. DWORD i;
  2241. DWORD j;
  2242. DWORD passw;
  2243. // LOCK(global_info.lock);
  2244. if (password != NULL)
  2245. {
  2246. #ifndef UNICODE
  2247. passw = License_string_encode (password);
  2248. #else
  2249. passw = License_wstring_encode((WCHAR*)password);
  2250. #endif
  2251. }
  2252. else
  2253. passw = CVY_DEF_RCT_PASSWORD;
  2254. if (cluster == WLBS_ALL_CLUSTERS)
  2255. {
  2256. /* when all clusters are targeted - change the default and go through
  2257. the entire parameter table setting new values */
  2258. m_def_passw = passw;
  2259. for (i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  2260. m_cluster_params [i] . passw = passw;
  2261. }
  2262. else
  2263. {
  2264. for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++)
  2265. {
  2266. /* mark an empty slot in case we will have to enter a new value */
  2267. if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0)
  2268. j = i;
  2269. if (m_cluster_params [i] . cluster == cluster)
  2270. {
  2271. m_cluster_params [i] . passw = passw;
  2272. break;
  2273. }
  2274. }
  2275. /* if we did not locate specified cluster in the table and there is an
  2276. empty slot - enter new cluster info in the table */
  2277. if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS)
  2278. {
  2279. m_cluster_params [j] . cluster = cluster;
  2280. m_cluster_params [j] . passw = passw;
  2281. }
  2282. }
  2283. // UNLOCK(global_info.lock);
  2284. } /* end WlbsPasswordSet */
  2285. VOID CWlbsControl::WlbsCodeSet
  2286. (
  2287. DWORD cluster,
  2288. DWORD passw
  2289. )
  2290. {
  2291. DWORD i;
  2292. DWORD j;
  2293. // LOCK(global_info.lock);
  2294. if (cluster == WLBS_ALL_CLUSTERS)
  2295. {
  2296. /* when all clusters are targeted - change the default and go through
  2297. the entire parameter table setting new values */
  2298. m_def_passw = passw;
  2299. for (i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  2300. m_cluster_params [i] . passw = passw;
  2301. }
  2302. else
  2303. {
  2304. for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++)
  2305. {
  2306. /* mark an empty slot in case we will have to enter a new value */
  2307. if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0)
  2308. j = i;
  2309. if (m_cluster_params [i] . cluster == cluster)
  2310. {
  2311. m_cluster_params [i] . passw = passw;
  2312. break;
  2313. }
  2314. }
  2315. /* if we did not locate specified cluster in the table and there is an
  2316. empty slot - enter new cluster info in the table */
  2317. if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS)
  2318. {
  2319. m_cluster_params [j] . cluster = cluster;
  2320. m_cluster_params [j] . passw = passw;
  2321. }
  2322. }
  2323. // UNLOCK(global_info.lock);
  2324. } /* end WlbsCodeSet */
  2325. VOID CWlbsControl::WlbsDestinationSet
  2326. (
  2327. DWORD cluster,
  2328. DWORD dest
  2329. )
  2330. {
  2331. DWORD i;
  2332. DWORD j;
  2333. // LOCK(global_info.lock);
  2334. if (cluster == WLBS_ALL_CLUSTERS)
  2335. {
  2336. /* when all clusters are targeted - change the default and go through
  2337. the entire parameter table setting new values */
  2338. m_def_dst_addr = dest;
  2339. for (i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  2340. m_cluster_params [i] . dest = dest;
  2341. }
  2342. else
  2343. {
  2344. for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++)
  2345. {
  2346. /* mark an empty slot in case we will have to enter a new value */
  2347. if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0)
  2348. j = i;
  2349. if (m_cluster_params [i] . cluster == cluster)
  2350. {
  2351. m_cluster_params [i] . dest = dest;
  2352. break;
  2353. }
  2354. }
  2355. /* if we did not locate specified cluster in the table and there is an
  2356. empty slot - enter new cluster info in the table */
  2357. if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS)
  2358. {
  2359. m_cluster_params [j] . cluster = cluster;
  2360. m_cluster_params [j] . dest = dest;
  2361. }
  2362. }
  2363. // UNLOCK(global_info.lock);
  2364. }
  2365. //+----------------------------------------------------------------------------
  2366. //
  2367. // Function: CWlbsControl::WlbsTimeoutSet
  2368. //
  2369. // Description:
  2370. //
  2371. // Arguments: DWORD cluster -
  2372. // DWORD milliseconds -
  2373. //
  2374. // Returns: Nothing
  2375. //
  2376. // History: fengsun Created Header 1/25/00
  2377. //
  2378. //+----------------------------------------------------------------------------
  2379. VOID CWlbsControl::WlbsTimeoutSet(DWORD cluster, DWORD milliseconds)
  2380. {
  2381. DWORD i;
  2382. DWORD j;
  2383. DWORD timeout;
  2384. // LOCK(global_info.lock);
  2385. if (milliseconds == 0)
  2386. timeout = IOCTL_REMOTE_RECV_DELAY;
  2387. else
  2388. timeout = milliseconds / (IOCTL_REMOTE_SEND_RETRIES *
  2389. IOCTL_REMOTE_RECV_RETRIES);
  2390. if (timeout < 10)
  2391. timeout = 10;
  2392. if (cluster == WLBS_ALL_CLUSTERS)
  2393. {
  2394. /* when all clusters are targeted - change the default and go through
  2395. the entire parameter table setting new values */
  2396. m_def_timeout = timeout;
  2397. for (i = 0; i < WLBS_MAX_CLUSTERS; i ++)
  2398. m_cluster_params [i] . timeout = timeout;
  2399. }
  2400. else
  2401. {
  2402. for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++)
  2403. {
  2404. /* mark an empty slot in case we will have to enter a new value */
  2405. if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0)
  2406. j = i;
  2407. if (m_cluster_params [i] . cluster == cluster)
  2408. {
  2409. m_cluster_params [i] . timeout = timeout;
  2410. break;
  2411. }
  2412. }
  2413. /* if we did not locate specified cluster in the table and there is an
  2414. empty slot - enter new cluster info in the table */
  2415. if (i >= WLBS_MAX_CLUSTERS && j < WLBS_MAX_CLUSTERS)
  2416. {
  2417. m_cluster_params [j] . cluster = cluster;
  2418. m_cluster_params [j] . timeout = timeout;
  2419. }
  2420. }
  2421. // UNLOCK(global_info.lock);
  2422. } /* end WlbsTimeoutSet */
  2423. #if defined (SBH)
  2424. DWORD CWlbsControl::WlbsQueryStateInfo (DWORD cluster, DWORD host, PIOCTL_QUERY_STATE bufp) {
  2425. IOCTL_LOCAL_HDR Header;
  2426. CWlbsCluster * pCluster = NULL;
  2427. LONG Ioctl = IOCTL_CVY_QUERY_STATE;
  2428. ULONG BufferSize = 0;
  2429. WCHAR Guid[128];
  2430. ULONG Length;
  2431. BOOLEAN Ret;
  2432. if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult();
  2433. pCluster = GetClusterFromIpOrIndex(cluster);
  2434. if (!pCluster) return WLBS_IO_ERROR;
  2435. StringFromGUID2(pCluster->GetAdapterGuid(), Guid, sizeof(Guid)/ sizeof(Guid[0]));
  2436. ZeroMemory((VOID *)&Header, sizeof(IOCTL_LOCAL_HDR));
  2437. lstrcpy(Header.device_name, L"\\device\\");
  2438. lstrcat(Header.device_name, Guid);
  2439. Header.options.state.flags = 0;
  2440. Header.options.state.query = *bufp;
  2441. switch (bufp->Operation) {
  2442. case NLB_QUERY_REG_PARAMS:
  2443. case NLB_QUERY_PORT_RULE_STATE:
  2444. case NLB_QUERY_BDA_TEAM_STATE:
  2445. case NLB_QUERY_PACKET_STATISTICS:
  2446. return WLBS_IO_ERROR;
  2447. case NLB_QUERY_PACKET_FILTER:
  2448. Ret = (BOOLEAN)DeviceIoControl(m_hdl, Ioctl, &Header, sizeof(IOCTL_LOCAL_HDR), &Header, sizeof(IOCTL_LOCAL_HDR), &Length, NULL);
  2449. if (!Ret || (Length != sizeof(IOCTL_LOCAL_HDR))) return WLBS_IO_ERROR;
  2450. break;
  2451. default:
  2452. return WLBS_IO_ERROR;
  2453. }
  2454. *bufp = Header.options.state.query;
  2455. return WLBS_OK;
  2456. }
  2457. #endif
  2458. //+----------------------------------------------------------------------------
  2459. //
  2460. // Function: DllMain
  2461. //
  2462. // Description: Dll entry point
  2463. //
  2464. // Arguments: HINSTANCE handle -
  2465. // DWORD reason -
  2466. // LPVOID situation -
  2467. //
  2468. // Returns: BOOL WINAPI -
  2469. //
  2470. // History: fengsun Created Header 3/2/00
  2471. //
  2472. //+----------------------------------------------------------------------------
  2473. BOOL WINAPI DllMain(HINSTANCE handle, DWORD reason, LPVOID situation)
  2474. {
  2475. switch (reason)
  2476. {
  2477. case DLL_PROCESS_ATTACH:
  2478. _tsetlocale (LC_ALL, _TEXT(".OCP"));
  2479. DisableThreadLibraryCalls(handle);
  2480. g_hInstCtrl = handle;
  2481. //
  2482. // Enable tracing
  2483. //
  2484. WPP_INIT_TRACING(L"Microsoft\\NLB");
  2485. break;
  2486. case DLL_THREAD_ATTACH:
  2487. break;
  2488. case DLL_PROCESS_DETACH:
  2489. //
  2490. // Disable tracing
  2491. //
  2492. WPP_CLEANUP();
  2493. break;
  2494. case DLL_THREAD_DETACH:
  2495. break;
  2496. default:
  2497. return FALSE;
  2498. }
  2499. return TRUE;
  2500. }