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.

741 lines
19 KiB

  1. #include <crtdbg.h>
  2. #include <comdef.h>
  3. #include <iostream>
  4. #include <memory>
  5. #include <string>
  6. #include <wbemprov.h>
  7. #include <genlex.h> //for wmi object path parser
  8. #include <objbase.h>
  9. #include <wlbsconfig.h>
  10. #include <ntrkcomm.h>
  11. using namespace std;
  12. #include "objpath.h"
  13. #include "debug.h"
  14. #include "controlwrapper.h"
  15. #include "clusterwrapper.h"
  16. #include "utils.h"
  17. #include "wlbsparm.h"
  18. #include "control.h"
  19. #define NLB_DEFAULT_TIMEOUT 10
  20. ////////////////////////////////////////////////////////////////////////////////
  21. //
  22. // FillResponseClass
  23. //
  24. // Purpose: This function is obsolete. It was used in old versions to fill a
  25. // a response parameter that was returned from the control methods
  26. // of the Node and Cluster classes.
  27. //
  28. ////////////////////////////////////////////////////////////////////////////////
  29. void FillResponseClass
  30. (
  31. DWORD a_dwNumHosts,
  32. const WLBS_RESPONSE a_Response[],
  33. WLBS_RESPONSE a_cResponse[],
  34. LPCSTR a_szcommand
  35. )
  36. {
  37. ASSERT( a_szcommand );
  38. if( a_Response && a_cResponse ) {
  39. for( DWORD nIter = 0; nIter < a_dwNumHosts; nIter++ ) {
  40. a_cResponse [nIter] = a_Response[nIter];
  41. //GetStatusDesc( a_cResponse[nIter].status, a_szcommand, a_cResponse[nIter].m_szStatus );
  42. }
  43. }
  44. }
  45. void CWlbsControlWrapper::Initialize()
  46. {
  47. DWORD dwRet = m_WlbsControl.Initialize();
  48. if( dwRet != WLBS_PRESENT && dwRet != WLBS_LOCAL_ONLY)
  49. throw CErrorWlbsControl( dwRet, CmdWlbsInit );
  50. m_WlbsControl.WlbsTimeoutSet( WLBS_ALL_CLUSTERS, NLB_DEFAULT_TIMEOUT );
  51. CWlbsCluster** ppCluster;
  52. DWORD dwNumClusters = 0;
  53. //
  54. // Use the local password for local query
  55. //
  56. m_WlbsControl.EnumClusterObjects( ppCluster, &dwNumClusters);
  57. for (int i=0;i<dwNumClusters;i++)
  58. {
  59. m_WlbsControl.WlbsCodeSet( ppCluster[i]->GetClusterIp(),
  60. ppCluster[i]->GetPassword() );
  61. }
  62. }
  63. void CWlbsControlWrapper::ReInitialize()
  64. {
  65. m_WlbsControl.ReInitialize();
  66. CWlbsCluster** ppCluster;
  67. DWORD dwNumClusters = 0;
  68. //
  69. // In case pasword is changed, use the local password for local query
  70. //
  71. m_WlbsControl.EnumClusterObjects( ppCluster, &dwNumClusters);
  72. for (int i=0;i<dwNumClusters;i++)
  73. {
  74. //
  75. // If the change is not commited, the driver will still has the old password
  76. //
  77. if (!ppCluster[i]->IsCommitPending())
  78. {
  79. m_WlbsControl.WlbsCodeSet( ppCluster[i]->GetClusterIp(),
  80. ppCluster[i]->GetPassword() );
  81. }
  82. }
  83. }
  84. void CWlbsControlWrapper::EnumClusters(CWlbsClusterWrapper** & ppCluster, DWORD* pdwNumClusters)
  85. {
  86. m_WlbsControl.EnumClusterObjects( (CWlbsCluster** &) ppCluster, pdwNumClusters);
  87. }
  88. ////////////////////////////////////////////////////////////////////////////////
  89. //
  90. // CWlbsControlWrapper::Disable
  91. //
  92. // Purpose: Disable ALL traffic handling for the rule containing the
  93. // specified port on specified host or all cluster hosts. Only rules
  94. // that are set for multiple host filtering mode are affected.
  95. //
  96. //
  97. ////////////////////////////////////////////////////////////////////////////////
  98. DWORD CWlbsControlWrapper::Disable
  99. (
  100. DWORD a_dwCluster ,
  101. DWORD a_dwHost ,
  102. WLBS_RESPONSE* a_pResponse ,
  103. DWORD& a_dwNumHosts ,
  104. DWORD a_dwVip ,
  105. DWORD a_dwPort
  106. )
  107. {
  108. DWORD dwRet;
  109. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  110. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  111. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  112. dwRet = m_WlbsControl.WlbsDisable( a_dwCluster ,
  113. a_dwHost ,
  114. Response ,
  115. &dwNumHosts ,
  116. a_dwVip ,
  117. a_dwPort
  118. );
  119. //check for Winsock errors
  120. if( dwRet > 10000 )
  121. {
  122. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  123. }
  124. //check the return value and throw if an error occurred
  125. switch( dwRet ) {
  126. case WLBS_INIT_ERROR:
  127. case WLBS_BAD_PASSW:
  128. case WLBS_TIMEOUT:
  129. case WLBS_LOCAL_ONLY:
  130. case WLBS_REMOTE_ONLY:
  131. case WLBS_IO_ERROR:
  132. throw CErrorWlbsControl( dwRet, CmdWlbsDisable, bClusterWide );
  133. break;
  134. }
  135. a_dwNumHosts = dwNumHosts;
  136. FillResponseClass( dwNumHosts, Response, a_pResponse, "disable" );
  137. return dwRet;
  138. }
  139. ////////////////////////////////////////////////////////////////////////////////
  140. //
  141. // CWlbsControlWrapper::Enable
  142. //
  143. // Purpose: Enable traffic handling for rule containing the
  144. // specified port on specified host or all cluster hosts. Only rules
  145. // that are set for multiple host filtering mode are affected.
  146. //
  147. //
  148. //
  149. ////////////////////////////////////////////////////////////////////////////////
  150. DWORD CWlbsControlWrapper::Enable
  151. (
  152. DWORD a_dwCluster ,
  153. DWORD a_dwHost ,
  154. WLBS_RESPONSE* a_pResponse ,
  155. DWORD& a_dwNumHosts ,
  156. DWORD a_dwVip ,
  157. DWORD a_dwPort
  158. )
  159. {
  160. DWORD dwRet;
  161. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  162. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  163. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  164. dwRet = m_WlbsControl.WlbsEnable( a_dwCluster ,
  165. a_dwHost ,
  166. Response ,
  167. &dwNumHosts ,
  168. a_dwVip ,
  169. a_dwPort
  170. );
  171. //check for Winsock errors
  172. if( dwRet > 10000 )
  173. {
  174. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  175. }
  176. //check the return value and throw if an error occurred
  177. switch(dwRet) {
  178. case WLBS_INIT_ERROR:
  179. case WLBS_BAD_PASSW:
  180. case WLBS_TIMEOUT:
  181. case WLBS_LOCAL_ONLY:
  182. case WLBS_REMOTE_ONLY:
  183. case WLBS_IO_ERROR:
  184. throw CErrorWlbsControl( dwRet, CmdWlbsEnable, bClusterWide );
  185. break;
  186. }
  187. a_dwNumHosts = dwNumHosts;
  188. FillResponseClass( dwNumHosts, Response, a_pResponse, "enable" );
  189. return dwRet;
  190. }
  191. ////////////////////////////////////////////////////////////////////////////////
  192. //
  193. // CWlbsControlWrapper::Drain
  194. //
  195. // Purpose: Disable NEW traffic handling for rule containing the specified
  196. // port on specified host or all cluster hosts. Only rules that are
  197. // set for multiple host filtering mode are affected.
  198. //
  199. //
  200. ////////////////////////////////////////////////////////////////////////////////
  201. DWORD CWlbsControlWrapper::Drain
  202. (
  203. DWORD a_dwCluster ,
  204. DWORD a_dwHost ,
  205. WLBS_RESPONSE* a_pResponse ,
  206. DWORD& a_dwNumHosts ,
  207. DWORD a_dwVip ,
  208. DWORD a_dwPort
  209. )
  210. {
  211. DWORD dwRet;
  212. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  213. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  214. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  215. dwRet = m_WlbsControl.WlbsDrain( a_dwCluster ,
  216. a_dwHost ,
  217. Response ,
  218. &dwNumHosts ,
  219. a_dwVip ,
  220. a_dwPort
  221. );
  222. //check for Winsock errors
  223. if( dwRet > 10000 )
  224. {
  225. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  226. }
  227. //check the return value and throw if an error occurred
  228. switch(dwRet) {
  229. case WLBS_INIT_ERROR:
  230. case WLBS_BAD_PASSW:
  231. case WLBS_TIMEOUT:
  232. case WLBS_LOCAL_ONLY:
  233. case WLBS_REMOTE_ONLY:
  234. case WLBS_IO_ERROR:
  235. throw CErrorWlbsControl( dwRet, CmdWlbsDrain, bClusterWide );
  236. break;
  237. }
  238. a_dwNumHosts = dwNumHosts;
  239. FillResponseClass( dwNumHosts, Response, a_pResponse, "drain" );
  240. return dwRet;
  241. }
  242. ////////////////////////////////////////////////////////////////////////////////
  243. //
  244. // CWlbsControlWrapper::DrainStop
  245. //
  246. // Purpose: Enter draining mode on specified host or all cluster hosts.
  247. // New connections will not be accepted. Cluster mode will be stopped
  248. // when all existing connections finish. While draining, host will
  249. // participate in convergence and remain part of the cluster.
  250. //
  251. //
  252. ////////////////////////////////////////////////////////////////////////////////
  253. DWORD CWlbsControlWrapper::DrainStop
  254. (
  255. DWORD a_dwCluster ,
  256. DWORD a_dwHost ,
  257. WLBS_RESPONSE* a_pResponse ,
  258. DWORD& a_dwNumHosts
  259. )
  260. {
  261. DWORD dwRet;
  262. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  263. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  264. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  265. dwRet = m_WlbsControl.WlbsDrainStop( a_dwCluster ,
  266. a_dwHost ,
  267. Response ,
  268. &dwNumHosts
  269. );
  270. //check for Winsock errors
  271. if( dwRet > 10000 )
  272. {
  273. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  274. }
  275. //check the return value and throw if an error occurred
  276. switch(dwRet) {
  277. case WLBS_INIT_ERROR:
  278. case WLBS_BAD_PASSW:
  279. case WLBS_TIMEOUT:
  280. case WLBS_LOCAL_ONLY:
  281. case WLBS_REMOTE_ONLY:
  282. case WLBS_IO_ERROR:
  283. throw CErrorWlbsControl( dwRet, CmdWlbsDrainStop, bClusterWide );
  284. break;
  285. }
  286. a_dwNumHosts = dwNumHosts;
  287. FillResponseClass( dwNumHosts, Response, a_pResponse, "drainstop" );
  288. return dwRet;
  289. }
  290. ////////////////////////////////////////////////////////////////////////////////
  291. //
  292. // CWlbsControlWrapper::Resume
  293. //
  294. // Purpose: Resume cluster operation control on specified host or all
  295. // cluster hosts.
  296. //
  297. //
  298. ////////////////////////////////////////////////////////////////////////////////
  299. DWORD CWlbsControlWrapper::Resume
  300. (
  301. DWORD a_dwCluster ,
  302. DWORD a_dwHost ,
  303. WLBS_RESPONSE* a_pResponse ,
  304. DWORD& a_dwNumHosts
  305. )
  306. {
  307. DWORD dwRet;
  308. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  309. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  310. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  311. dwRet = m_WlbsControl.WlbsResume(
  312. a_dwCluster ,
  313. a_dwHost ,
  314. Response ,
  315. &dwNumHosts
  316. );
  317. //check for Winsock errors
  318. if( dwRet > 10000 )
  319. {
  320. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  321. }
  322. //check the return value and throw if an error occurred
  323. switch(dwRet) {
  324. case WLBS_INIT_ERROR:
  325. case WLBS_BAD_PASSW:
  326. case WLBS_TIMEOUT:
  327. case WLBS_LOCAL_ONLY:
  328. case WLBS_REMOTE_ONLY:
  329. case WLBS_IO_ERROR:
  330. throw CErrorWlbsControl( dwRet, CmdWlbsResume, bClusterWide );
  331. break;
  332. }
  333. a_dwNumHosts = dwNumHosts;
  334. FillResponseClass( dwNumHosts, Response, a_pResponse, "resume" );
  335. return dwRet;
  336. }
  337. ////////////////////////////////////////////////////////////////////////////////
  338. //
  339. // CWlbsControlWrapper::Start
  340. //
  341. // Purpose: Start cluster operations on specified host or all cluster hosts.
  342. //
  343. //
  344. ////////////////////////////////////////////////////////////////////////////////
  345. DWORD CWlbsControlWrapper::Start
  346. (
  347. DWORD a_dwCluster ,
  348. DWORD a_dwHost ,
  349. WLBS_RESPONSE* a_pResponse ,
  350. DWORD& a_dwNumHosts
  351. )
  352. {
  353. DWORD dwRet;
  354. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  355. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  356. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  357. dwRet = m_WlbsControl.WlbsStart( a_dwCluster ,
  358. a_dwHost ,
  359. Response ,
  360. &dwNumHosts
  361. );
  362. //check for Winsock errors
  363. if( dwRet > 10000 )
  364. {
  365. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  366. }
  367. //check the return value and throw if an error occurred
  368. switch(dwRet) {
  369. case WLBS_INIT_ERROR:
  370. case WLBS_BAD_PASSW:
  371. case WLBS_TIMEOUT:
  372. case WLBS_LOCAL_ONLY:
  373. case WLBS_REMOTE_ONLY:
  374. case WLBS_IO_ERROR:
  375. throw CErrorWlbsControl( dwRet, CmdWlbsStart, bClusterWide );
  376. break;
  377. }
  378. a_dwNumHosts = dwNumHosts;
  379. FillResponseClass( dwNumHosts, Response, a_pResponse, "start" );
  380. return dwRet;
  381. }
  382. ////////////////////////////////////////////////////////////////////////////////
  383. //
  384. // CWlbsControlWrapper::Stop
  385. //
  386. // Purpose: Stop cluster operations on specified host or all cluster hosts.
  387. //
  388. //
  389. ////////////////////////////////////////////////////////////////////////////////
  390. DWORD CWlbsControlWrapper::Stop
  391. (
  392. DWORD a_dwCluster ,
  393. DWORD a_dwHost ,
  394. WLBS_RESPONSE* a_pResponse ,
  395. DWORD& a_dwNumHosts
  396. )
  397. {
  398. DWORD dwRet;
  399. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  400. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  401. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  402. dwRet = m_WlbsControl.WlbsStop(
  403. a_dwCluster ,
  404. a_dwHost ,
  405. Response ,
  406. &dwNumHosts
  407. );
  408. //check for Winsock errors
  409. if( dwRet > 10000 )
  410. {
  411. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  412. }
  413. //check the return value and throw if an error occurred
  414. switch(dwRet) {
  415. case WLBS_INIT_ERROR:
  416. case WLBS_BAD_PASSW:
  417. case WLBS_TIMEOUT:
  418. case WLBS_LOCAL_ONLY:
  419. case WLBS_REMOTE_ONLY:
  420. case WLBS_IO_ERROR:
  421. throw CErrorWlbsControl( dwRet, CmdWlbsStop, bClusterWide );
  422. break;
  423. }
  424. a_dwNumHosts = dwNumHosts;
  425. FillResponseClass( dwNumHosts, Response, a_pResponse, "stop" );
  426. return dwRet;
  427. }
  428. ////////////////////////////////////////////////////////////////////////////////
  429. //
  430. // CWlbsControlWrapper::Suspend
  431. //
  432. // Purpose: Suspend cluster operation control on specified host or
  433. // all cluster hosts.
  434. //
  435. //
  436. ////////////////////////////////////////////////////////////////////////////////
  437. DWORD CWlbsControlWrapper::Suspend
  438. (
  439. DWORD a_dwCluster ,
  440. DWORD a_dwHost ,
  441. WLBS_RESPONSE* a_pResponse ,
  442. DWORD& a_dwNumHosts
  443. )
  444. {
  445. DWORD dwRet;
  446. BOOL bClusterWide = ( a_dwNumHosts == WLBS_ALL_HOSTS );
  447. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  448. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  449. dwRet = m_WlbsControl.WlbsSuspend( a_dwCluster ,
  450. a_dwHost ,
  451. Response ,
  452. &dwNumHosts
  453. );
  454. //check for Winsock errors
  455. if( dwRet > 10000 )
  456. {
  457. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  458. }
  459. //check the return value and throw if an error occurred
  460. switch(dwRet) {
  461. case WLBS_INIT_ERROR:
  462. case WLBS_BAD_PASSW:
  463. case WLBS_TIMEOUT:
  464. case WLBS_LOCAL_ONLY:
  465. case WLBS_REMOTE_ONLY:
  466. case WLBS_IO_ERROR:
  467. throw CErrorWlbsControl( dwRet, CmdWlbsSuspend, bClusterWide );
  468. break;
  469. }
  470. a_dwNumHosts = dwNumHosts;
  471. FillResponseClass( dwNumHosts, Response, a_pResponse, "suspend" );
  472. return dwRet;
  473. }
  474. ////////////////////////////////////////////////////////////////////////////////
  475. //
  476. // CWlbsControlWrapper::Query
  477. //
  478. // Purpose: This invokes WlbsQuery and returns a response structure along
  479. // with other parameters if requested.
  480. //
  481. // Errors: The function throws CErrorWlbsControl.
  482. //
  483. // Return: Status value returned by the target host
  484. //
  485. ////////////////////////////////////////////////////////////////////////////////
  486. DWORD CWlbsControlWrapper::Query
  487. (
  488. CWlbsClusterWrapper* pCluster,
  489. DWORD a_dwHost ,
  490. WLBS_RESPONSE* a_pResponse ,
  491. PDWORD a_pdwNumHosts ,
  492. PDWORD a_pdwHostMap
  493. )
  494. {
  495. DWORD dwResponseSize = 0;
  496. if (a_pdwNumHosts)
  497. {
  498. dwResponseSize = *a_pdwNumHosts;
  499. *a_pdwNumHosts = 0;
  500. }
  501. DWORD dwRet;
  502. BOOL bClusterWide = 0;
  503. bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS );
  504. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  505. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  506. dwRet = m_WlbsControl.WlbsQuery(
  507. (CWlbsCluster*)pCluster ,
  508. a_dwHost ,
  509. Response ,
  510. &dwNumHosts ,
  511. a_pdwHostMap,
  512. NULL
  513. );
  514. string strOut;
  515. //check for Winsock errors
  516. if( dwRet > 10000 )
  517. {
  518. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  519. }
  520. //check the return value and throw if an error occurred
  521. switch( dwRet ) {
  522. case WLBS_INIT_ERROR:
  523. case WLBS_BAD_PASSW:
  524. case WLBS_TIMEOUT:
  525. case WLBS_LOCAL_ONLY:
  526. case WLBS_REMOTE_ONLY:
  527. case WLBS_IO_ERROR:
  528. throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide );
  529. }
  530. //local queries do not return the dedicated IP
  531. //get the dedicated IP and fill the structure
  532. if( a_dwHost == WLBS_LOCAL_HOST )
  533. {
  534. Response[0].address = pCluster->GetDedicatedIp();
  535. }
  536. if( a_pdwNumHosts )
  537. {
  538. *a_pdwNumHosts = _MIN(dwResponseSize, dwNumHosts);
  539. FillResponseClass( dwNumHosts, Response, a_pResponse, "query" );
  540. }
  541. return dwRet;
  542. }
  543. ////////////////////////////////////////////////////////////////////////////////
  544. //
  545. // CWlbsClusterWrapper::CheckMembership
  546. //
  547. // Purpose: This verifies that the local host is a member of the cluster
  548. // specified by the Cluster IP in the registry. At the time this
  549. // was written, there was a remote chance that a user can modify the
  550. // IP address in the registry prior to the load of this DLL.
  551. //
  552. // Note, this call is only required for the Node, Cluster and linked
  553. // associations and should not be invoked for any of the Setting classes.
  554. //
  555. ////////////////////////////////////////////////////////////////////////////////
  556. void CWlbsControlWrapper::CheckMembership()
  557. {
  558. // todo: make sure the host is in at least one cluster
  559. /*
  560. WLBS_RESPONSE WlbsResponse;
  561. DWORD dwResSize = 1;
  562. //get the cluster and HostID
  563. DWORD dwRes = pControl->Query( m_pWlbsCluster->GetClusterIp(),
  564. WLBS_LOCAL_HOST,
  565. &WlbsResponse,
  566. &dwResSize,
  567. NULL);
  568. switch( dwRes ) {
  569. case WLBS_SUSPENDED:
  570. case WLBS_STOPPED:
  571. case WLBS_CONVERGING:
  572. case WLBS_DRAINING:
  573. case WLBS_CONVERGED:
  574. case WLBS_DEFAULT:
  575. break;
  576. default:
  577. throw CErrorWlbsControl( dwRes, CmdWlbsQuery );
  578. }
  579. */
  580. // DWORD dwClusterIP;
  581. // GetClusterIP( &dwClusterIP );
  582. //if( dwClusterIP == 0 )
  583. //throw _com_error( WBEM_E_NOT_FOUND );
  584. //*******************************
  585. //this section does not work when the remote control is disabled
  586. //on the local host
  587. //*******************************
  588. //call the query function
  589. // dwRes = WlbsQuery( dwClusterIP,
  590. // WlbsResponse.id,
  591. // NULL,
  592. // NULL,
  593. // NULL,
  594. // NULL );
  595. //analyze query results for errors
  596. // switch( dwRes ) {
  597. // case WLBS_OK:
  598. // case WLBS_STOPPED:
  599. // case WLBS_CONVERGING:
  600. // case WLBS_CONVERGED:
  601. // case WLBS_DEFAULT:
  602. // case WLBS_DRAINING:
  603. // case WLBS_SUSPENDED:
  604. // return;
  605. // default:
  606. // throw CErrorWlbsControl( dwRes, CmdWlbsQuery );
  607. // }
  608. //*******************************
  609. //this section does not work when the remote control is disabled
  610. //on the local host
  611. //*******************************
  612. }