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.

928 lines
25 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. iislbc.cxx
  5. Abstract:
  6. Command line utility to set/get IIS load balancing configuration
  7. Author:
  8. Philippe Choquier (phillich)
  9. --*/
  10. //#define INITGUID
  11. extern "C" {
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <ntsecapi.h>
  16. #include <windows.h>
  17. #include <winsock2.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20. #include <ipnat.h>
  21. #if 0
  22. typedef NTSTATUS
  23. (*PNAT_REGISTER_SESSION_CONTROL)(
  24. IN ULONG Version
  25. );
  26. typedef NTSTATUS
  27. (*PNAT_IOCTL_SESSION_CONTROL)(
  28. IN PIRP Irp
  29. );
  30. #endif
  31. }
  32. #include <stdio.h>
  33. #include <ole2.h>
  34. #include <pdh.h>
  35. #include <IisLb.h>
  36. #include <lbxbf.hxx>
  37. #include <lbcnfg.hxx>
  38. #include <IisLbs.hxx>
  39. #include <bootexp.hxx>
  40. #include "iisrc.h"
  41. //
  42. // HRESULTTOWIN32() maps an HRESULT to a Win32 error. If the facility code
  43. // of the HRESULT is FACILITY_WIN32, then the code portion (i.e. the
  44. // original Win32 error) is returned. Otherwise, the original HRESULT is
  45. // returned unchagned.
  46. //
  47. #define HRESULTTOWIN32(hres) \
  48. ((HRESULT_FACILITY(hres) == FACILITY_WIN32) \
  49. ? HRESULT_CODE(hres) \
  50. : (hres))
  51. #define RETURNCODETOHRESULT(rc) \
  52. (((rc) < 0x10000) \
  53. ? HRESULT_FROM_WIN32(rc) \
  54. : (rc))
  55. enum LB_CMD {
  56. CMD_NONE,
  57. CMD_ADD_SERVER,
  58. CMD_ADD_IP,
  59. CMD_ADD_PERFMON,
  60. CMD_DEL_SERVER,
  61. CMD_DEL_IP,
  62. CMD_DEL_PERFMON,
  63. #if 0
  64. CMD_SET_STICKY,
  65. #endif
  66. CMD_SET_IP,
  67. CMD_LIST,
  68. CMD_LIST_IP_ENDPOINTS,
  69. CMD_START_DRIVER,
  70. CMD_STOP_DRIVER,
  71. } ;
  72. #define LEN_SERVER_NAME 16
  73. #define LEN_IP (4*3+3+1+3)
  74. #define LEN_PERF 40
  75. extern CKernelIpMapHelper g_KernelIpMap;
  76. extern WSADATA g_WSAData;
  77. BOOL
  78. LocatePerfCounter(
  79. CComputerPerfCounters* pPerfCounters,
  80. LPWSTR pszSrv,
  81. LPWSTR pszParam,
  82. UINT* piPerfCounter
  83. )
  84. {
  85. UINT i;
  86. LPWSTR pszS;
  87. LPWSTR psz;
  88. DWORD dw;
  89. if ( pszSrv && (*pszSrv == L'\0' || !wcscmp(pszSrv,L"*")) )
  90. {
  91. pszSrv = NULL;
  92. }
  93. for ( i = 0 ;
  94. pPerfCounters->EnumPerfCounter( i, &pszS, &psz, &dw ) ;
  95. ++i )
  96. {
  97. if ( ((pszS == NULL) == (pszSrv==NULL)) &&
  98. !_wcsicmp( psz, pszParam ) )
  99. {
  100. *piPerfCounter = i;
  101. return TRUE;
  102. }
  103. }
  104. SetLastError( ERROR_INVALID_PARAMETER );
  105. return FALSE;
  106. }
  107. BOOL
  108. LocateServer(
  109. CIPMap* IpMap,
  110. LPWSTR pszParam,
  111. UINT* piServer
  112. )
  113. {
  114. UINT i;
  115. LPWSTR psz;
  116. for ( i = 0 ;
  117. IpMap->EnumComputer( i, &psz ) ;
  118. ++ i )
  119. {
  120. if ( !_wcsicmp( psz, pszParam ) )
  121. {
  122. *piServer = i;
  123. return TRUE;
  124. }
  125. }
  126. SetLastError( ERROR_INVALID_PARAMETER );
  127. return FALSE;
  128. }
  129. BOOL
  130. LocatePublicIp(
  131. CIPMap* IpMap,
  132. LPWSTR pszParam,
  133. UINT* piRes
  134. )
  135. {
  136. UINT i;
  137. LPWSTR psz;
  138. LPWSTR pszName;
  139. DWORD dwSticky;
  140. DWORD dwAttr;
  141. for ( i = 0 ;
  142. IpMap->EnumIpPublic( i, &psz, &pszName, &dwSticky, &dwAttr ) ;
  143. ++i )
  144. {
  145. if ( !_wcsicmp( psz, pszParam ) )
  146. {
  147. *piRes = i;
  148. return TRUE;
  149. }
  150. }
  151. SetLastError( ERROR_INVALID_PARAMETER );
  152. return FALSE;
  153. }
  154. VOID
  155. DisplayErrorMessage(
  156. DWORD dwErr
  157. )
  158. {
  159. LPWSTR pErr;
  160. if ( FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  161. NULL,
  162. dwErr,
  163. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  164. (LPWSTR)&pErr,
  165. 0,
  166. NULL ) )
  167. {
  168. LPWSTR p;
  169. if ( p = wcschr( pErr, L'\r' ) )
  170. {
  171. *p = L'\0';
  172. }
  173. fputws( pErr, stdout );
  174. LocalFree( pErr );
  175. }
  176. }
  177. BOOL
  178. ChooseCounter(
  179. LPWSTR pszCounterBuffer
  180. )
  181. {
  182. PDH_BROWSE_DLG_CONFIG_W BrowseInfo;
  183. PDH_STATUS pdhStatus;
  184. LPWSTR pszPostServerName;
  185. WCHAR achSelect[128];
  186. if ( !LoadStringW( NULL, IDS_LBC_SP, achSelect, sizeof(achSelect) ) )
  187. {
  188. achSelect[0] = L'\0';
  189. }
  190. #if defined(_X86_) && 0
  191. __asm int 3
  192. #endif
  193. BrowseInfo.bIncludeInstanceIndex = FALSE;
  194. BrowseInfo.bSingleCounterPerAdd = TRUE;
  195. BrowseInfo.bSingleCounterPerDialog = TRUE;
  196. BrowseInfo.bLocalCountersOnly = FALSE;
  197. BrowseInfo.bWildCardInstances = FALSE;
  198. BrowseInfo.bHideDetailBox = FALSE;
  199. BrowseInfo.bInitializePath = FALSE;
  200. BrowseInfo.bDisableMachineSelection = FALSE;
  201. BrowseInfo.bIncludeCostlyObjects = TRUE;
  202. BrowseInfo.hWndOwner = GetActiveWindow();
  203. BrowseInfo.szDataSource = NULL;
  204. BrowseInfo.szReturnPathBuffer = pszCounterBuffer;
  205. BrowseInfo.cchReturnPathLength = MAX_PATH;
  206. BrowseInfo.pCallBack = NULL;
  207. BrowseInfo.dwCallBackArg = 0;
  208. BrowseInfo.CallBackStatus = ERROR_SUCCESS;
  209. BrowseInfo.dwDefaultDetailLevel = PERF_DETAIL_WIZARD;
  210. BrowseInfo.szDialogBoxCaption = achSelect;
  211. if ( PdhBrowseCountersW (&BrowseInfo) == ERROR_SUCCESS )
  212. {
  213. if ( !memcmp( pszCounterBuffer, L"\\\\", 2*sizeof(WCHAR) ) &&
  214. (pszPostServerName = wcschr( pszCounterBuffer+2, L'\\' )) )
  215. {
  216. memmove( pszCounterBuffer, pszPostServerName, (wcslen(pszPostServerName)+1)*sizeof(WCHAR) );
  217. }
  218. return TRUE;
  219. }
  220. return FALSE;
  221. }
  222. #if 0
  223. VOID
  224. TestDriver(
  225. )
  226. {
  227. HMODULE hMod;
  228. PNAT_REGISTER_SESSION_CONTROL pfnNatRegisterSessionControl;
  229. PNAT_IOCTL_SESSION_CONTROL pfnNatIoctlSessionControl;
  230. PNAT_DIRECTOR_QUERY_SESSION pfnNatQuerySessionControl;
  231. IRP Irp;
  232. ULONG PrivateAddr;
  233. USHORT PrivatePort;
  234. ULONG PublicAddr;
  235. USHORT PublicPort;
  236. ULONG RemoteAddr;
  237. USHORT RemotePort;
  238. CKernelServerDescription* pS;
  239. UINT iS;
  240. UINT iP;
  241. IO_STACK_LOCATION IrpSp;
  242. LPVOID pv;
  243. #if 0
  244. UINT x;
  245. UINT c;
  246. UINT f;
  247. UINT y;
  248. for ( c = 0, x = 2 ; x < 1000 ; ++x )
  249. {
  250. f = TRUE;
  251. for ( y = 2 ; y * y < x ; ++y )
  252. {
  253. if ( x % y == 0 )
  254. {
  255. f = FALSE;
  256. break;
  257. }
  258. }
  259. if ( f )
  260. {
  261. wprintf( L"%d\t", x );
  262. if ( (++c & 7) == 7 )
  263. {
  264. wprintf(L"\n");
  265. }
  266. }
  267. }
  268. #endif
  269. if ( (hMod = LoadLibraryW( L"iislbdr.dll" )) )
  270. {
  271. pfnNatRegisterSessionControl = (PNAT_REGISTER_SESSION_CONTROL)GetProcAddress( hMod,
  272. "NatRegisterSessionControl" );
  273. pfnNatIoctlSessionControl = (PNAT_IOCTL_SESSION_CONTROL)GetProcAddress( hMod,
  274. "NatIoctlSessionControl" );
  275. pfnNatQuerySessionControl = (PNAT_DIRECTOR_QUERY_SESSION)GetProcAddress( hMod,
  276. "NatQuerySessionControl" );
  277. if ( pfnNatRegisterSessionControl &&
  278. pfnNatIoctlSessionControl &&
  279. pfnNatQuerySessionControl )
  280. {
  281. if ( WSAStartup( MAKEWORD( 2, 0), &g_WSAData ) == 0 &&
  282. InitGlobals() )
  283. {
  284. PublicAddr = 0x04030201;
  285. PublicPort = 0x5000;
  286. RemoteAddr = 0x0f0f0f0f;
  287. RemotePort = 0xf000;
  288. pfnNatRegisterSessionControl( 1 );
  289. for ( iS = 0;
  290. iS < g_KernelIpMap.ServerCount() ;
  291. ++iS )
  292. {
  293. pS = g_KernelIpMap.GetServerPtr( iS );
  294. pS->m_dwLoadAvail = 100;
  295. pS->m_LoadbalancedLoadAvail = pS->m_dwLoadAvail;
  296. }
  297. // refcount set to != 0
  298. for ( iP = 0;
  299. iP < g_KernelIpMap.PrivateIpCount() ;
  300. ++iP )
  301. {
  302. g_KernelIpMap.GetPrivateIpEndpoint( iP )->m_dwIndex = 1;
  303. }
  304. #if defined(_X86_)
  305. __asm int 3
  306. #endif
  307. g_KernelIpMap.GetPublicIpPtr( 0 )->m_dwNotifyPort = 0x5000;
  308. g_KernelIpMap.GetPublicIpPtr( 0 )->m_usUniquePort = 0x5000;
  309. IoGetCurrentIrpStackLocation( &Irp ) = &IrpSp;
  310. IrpSp.Parameters.DeviceIoControl.InputBufferLength = g_KernelIpMap.GetSize();
  311. Irp.AssociatedIrp.SystemBuffer = g_KernelIpMap.GetBuffer();
  312. pfnNatIoctlSessionControl( &Irp );
  313. pfnNatIoctlSessionControl( &Irp );
  314. pfnNatQuerySessionControl( NULL, NAT_PROTOCOL_TCP,
  315. PublicAddr, PublicPort,
  316. RemoteAddr, RemotePort,
  317. &PrivateAddr, &PrivatePort,
  318. &pv );
  319. // test cache
  320. pfnNatQuerySessionControl( NULL, NAT_PROTOCOL_TCP,
  321. PublicAddr, PublicPort,
  322. RemoteAddr, RemotePort,
  323. &PrivateAddr, &PrivatePort,
  324. &pv );
  325. // test new public IP addr
  326. PublicAddr = 0x05030201;
  327. PublicPort = 0x5000;
  328. pfnNatQuerySessionControl( NULL, NAT_PROTOCOL_TCP,
  329. PublicAddr, PublicPort,
  330. RemoteAddr, RemotePort,
  331. &PrivateAddr, &PrivatePort,
  332. &pv );
  333. // test invalid public IP addr
  334. PublicAddr = 0xff030201;
  335. PublicPort = 0x5000;
  336. pfnNatQuerySessionControl( NULL, NAT_PROTOCOL_TCP,
  337. PublicAddr, PublicPort,
  338. RemoteAddr, RemotePort,
  339. &PrivateAddr, &PrivatePort,
  340. &pv );
  341. pfnNatIoctlSessionControl( &Irp );
  342. }
  343. TerminateGlobals();
  344. }
  345. else
  346. {
  347. DisplayErrorMessage( GetLastError() );
  348. }
  349. FreeLibrary( hMod );
  350. }
  351. else
  352. {
  353. DisplayErrorMessage( GetLastError() );
  354. }
  355. }
  356. #endif
  357. BYTE abSerialized[32768];
  358. #define RC_BUFF achMsg
  359. #define RC_PRINTF(a,b) if ( LoadStringW( NULL, a, achMsg, sizeof(achMsg) ) ) wprintf b;
  360. LPWSTR
  361. ToUnicode(
  362. LPSTR psz
  363. )
  364. {
  365. LPWSTR ps = (LPWSTR)LocalAlloc( LMEM_FIXED, (strlen(psz)+1)*sizeof(WCHAR) );
  366. if ( ps )
  367. {
  368. if ( !MultiByteToWideChar( CP_ACP,
  369. MB_PRECOMPOSED,
  370. psz,
  371. -1,
  372. ps,
  373. (strlen(psz)+1) ) )
  374. {
  375. *ps = L'\0';
  376. }
  377. return ps;
  378. }
  379. return L"";
  380. }
  381. int __cdecl main(
  382. int argc,
  383. CHAR* argv[]
  384. )
  385. {
  386. int Status = 0;
  387. HRESULT hRes;
  388. LPSTR pszMachineName = NULL;
  389. COSERVERINFO csiMachineName;
  390. MULTI_QI rgmq;
  391. IClassFactory* pcsfFactory = NULL;
  392. IMSIisLb* pIisLb = NULL;
  393. WCHAR awchComputer[64];
  394. CIPMap IpMap;
  395. CComputerPerfCounters PerfCounters;
  396. CIpEndpointList IpEndpoints;
  397. DWORD dwSticky;
  398. DWORD dwReq;
  399. LPBYTE pbSerialized;
  400. int arg;
  401. int cParam;
  402. LPWSTR apszParam[16];
  403. LB_CMD iCmd = CMD_NONE;
  404. BOOL fUpdateIpMap = FALSE;
  405. BOOL fUpdatePerfCounters = FALSE;
  406. BOOL fUpdateSticky = FALSE;
  407. UINT iServer;
  408. UINT iPublicIp;
  409. UINT iPerfCounter;
  410. XBF xbf;
  411. LPWSTR pszPublicIp;
  412. LPWSTR pszPrivateIp;
  413. LPWSTR pszServer;
  414. LPWSTR pszName;
  415. LPWSTR pszPerfCounter;
  416. DWORD dwWeight;
  417. WCHAR achCounterBuffer[MAX_PATH];
  418. WCHAR achMsg[1024];
  419. DWORD dwAttr;
  420. if ( argc < 2 )
  421. {
  422. RC_PRINTF( IDS_LBC_HELP, (RC_BUFF) );
  423. return 3;
  424. }
  425. else
  426. {
  427. RC_PRINTF( IDS_LBC_COPYRIGHT, (RC_BUFF) );
  428. }
  429. cParam = 0;
  430. for ( arg = 1 ; arg < argc ; ++arg )
  431. {
  432. if ( argv[arg][0] == '-' )
  433. {
  434. switch ( argv[arg][1] )
  435. {
  436. case 'm':
  437. pszMachineName = argv[arg]+2;
  438. break;
  439. case 'a':
  440. switch ( argv[arg][2] )
  441. {
  442. case 's':
  443. iCmd = CMD_ADD_SERVER; break;
  444. case 'i':
  445. iCmd = CMD_ADD_IP; break;
  446. case 'p':
  447. iCmd = CMD_ADD_PERFMON; break;
  448. }
  449. break;
  450. case 'd':
  451. switch ( argv[arg][2] )
  452. {
  453. case 's':
  454. iCmd = CMD_DEL_SERVER; break;
  455. case 'i':
  456. iCmd = CMD_DEL_IP; break;
  457. case 'p':
  458. iCmd = CMD_DEL_PERFMON; break;
  459. }
  460. break;
  461. case 's':
  462. switch ( argv[arg][2] )
  463. {
  464. #if 0
  465. case 's':
  466. iCmd = CMD_SET_STICKY; break;
  467. #endif
  468. case 'i':
  469. iCmd = CMD_SET_IP; break;
  470. }
  471. break;
  472. case 'l':
  473. switch ( argv[arg][2] )
  474. {
  475. case 'e':
  476. iCmd = CMD_LIST_IP_ENDPOINTS; break;
  477. case 'c':
  478. iCmd = CMD_LIST;
  479. }
  480. break;
  481. #if 0
  482. case 't':
  483. TestDriver();
  484. return 0;
  485. #endif
  486. case '0':
  487. iCmd = CMD_STOP_DRIVER;
  488. break;
  489. case '1':
  490. iCmd = CMD_START_DRIVER;
  491. break;
  492. }
  493. }
  494. else if ( cParam < sizeof(apszParam)/sizeof(LPWSTR) )
  495. {
  496. apszParam[cParam++] = ToUnicode( argv[arg] );
  497. }
  498. }
  499. //fill the structure for CoCreateInstanceEx
  500. ZeroMemory( &csiMachineName, sizeof(csiMachineName) );
  501. if ( pszMachineName )
  502. {
  503. if ( !MultiByteToWideChar( CP_ACP,
  504. MB_PRECOMPOSED,
  505. pszMachineName,
  506. -1,
  507. awchComputer,
  508. sizeof(awchComputer) ) )
  509. {
  510. return FALSE;
  511. }
  512. csiMachineName.pwszName = awchComputer;
  513. }
  514. else
  515. {
  516. csiMachineName.pwszName = NULL;
  517. }
  518. CoInitializeEx( NULL, COINIT_MULTITHREADED );
  519. #if 0
  520. hRes = CoGetClassObject(CLSID_MSIisLb, CLSCTX_SERVER, &csiMachineName,
  521. IID_IClassFactory, (void**) &pcsfFactory);
  522. if ( SUCCEEDED( hRes ) )
  523. {
  524. hRes = pcsfFactory->CreateInstance(NULL, IID_IMSIisLb, (void **) &rgmq.pItf);
  525. if ( SUCCEEDED( hRes ) )
  526. #else
  527. if ( 1 )
  528. {
  529. rgmq.pIID = &IID_IMSIisLb;
  530. rgmq.hr = 0;
  531. rgmq.pItf = NULL;
  532. hRes = CoCreateInstanceEx( CLSID_MSIisLb, NULL, CLSCTX_SERVER, &csiMachineName, 1, &rgmq );
  533. if ( SUCCEEDED( hRes ) && SUCCEEDED( rgmq.hr ) )
  534. #endif
  535. {
  536. pIisLb = (IMSIisLb*)rgmq.pItf;
  537. // get current configuration
  538. if ( SUCCEEDED( hRes = pIisLb->GetIpList( sizeof(abSerialized), abSerialized, &dwReq ) ) )
  539. {
  540. pbSerialized = abSerialized;
  541. hRes = IpMap.Unserialize( &pbSerialized, &dwReq ) ? S_OK : RETURNCODETOHRESULT(ERROR_BAD_CONFIGURATION);
  542. }
  543. if ( SUCCEEDED( hRes ) &&
  544. SUCCEEDED( hRes = pIisLb->GetPerfmonCounters( sizeof(abSerialized), abSerialized, &dwReq ) ) )
  545. {
  546. pbSerialized = abSerialized;
  547. hRes = PerfCounters.Unserialize( &pbSerialized, &dwReq ) ? S_OK : RETURNCODETOHRESULT(ERROR_BAD_CONFIGURATION);
  548. }
  549. #if 0
  550. if ( SUCCEEDED( hRes ) )
  551. {
  552. hRes = pIisLb->GetStickyDuration( &dwSticky );
  553. }
  554. #endif
  555. if ( SUCCEEDED( hRes ) &&
  556. SUCCEEDED( hRes = pIisLb->GetIpEndpointList( sizeof(abSerialized), abSerialized, &dwReq ) ) )
  557. {
  558. pbSerialized = abSerialized;
  559. hRes = IpEndpoints.Unserialize( &pbSerialized, &dwReq ) ? S_OK : RETURNCODETOHRESULT(ERROR_BAD_CONFIGURATION);
  560. }
  561. if ( FAILED(hRes) )
  562. {
  563. pIisLb->Release();
  564. }
  565. }
  566. #if 0
  567. pcsfFactory->Release();
  568. #endif
  569. }
  570. if ( SUCCEEDED( hRes ) )
  571. {
  572. switch ( iCmd )
  573. {
  574. case CMD_START_DRIVER:
  575. hRes = pIisLb->SetDriverState( SERVICE_RUNNING );
  576. break;
  577. case CMD_STOP_DRIVER:
  578. hRes = pIisLb->SetDriverState( SERVICE_STOPPED );
  579. break;
  580. case CMD_ADD_SERVER:
  581. if ( cParam == 1 &&
  582. IpMap.AddComputer( apszParam[0] ) )
  583. {
  584. fUpdateIpMap = TRUE;
  585. }
  586. else
  587. {
  588. hRes = RETURNCODETOHRESULT(GetLastError());
  589. }
  590. break;
  591. case CMD_ADD_IP:
  592. if ( cParam == 3 &&
  593. IpMap.AddIpPublic( apszParam[0], apszParam[1], _wtoi(apszParam[2]), 0 ) )
  594. {
  595. fUpdateIpMap = TRUE;
  596. }
  597. else
  598. {
  599. hRes = RETURNCODETOHRESULT(GetLastError());
  600. }
  601. break;
  602. case CMD_ADD_PERFMON:
  603. if ( cParam >= 2 &&
  604. !wcscmp( apszParam[1], L"*" ) )
  605. {
  606. if ( ChooseCounter( achCounterBuffer ) )
  607. {
  608. apszParam[1] = achCounterBuffer;
  609. }
  610. else
  611. {
  612. cParam = 0;
  613. }
  614. }
  615. // server name : * for all
  616. if ( cParam >= 1 &&
  617. !wcscmp( apszParam[0], L"*" ) )
  618. {
  619. apszParam[0] = NULL;
  620. }
  621. if ( cParam == 3 &&
  622. PerfCounters.AddPerfCounter( apszParam[0], apszParam[1], _wtoi(apszParam[2]) ) )
  623. {
  624. fUpdatePerfCounters = TRUE;
  625. }
  626. else
  627. {
  628. hRes = RETURNCODETOHRESULT(GetLastError());
  629. }
  630. break;
  631. case CMD_DEL_SERVER:
  632. if ( cParam == 1 &&
  633. LocateServer( &IpMap, apszParam[0], &iServer ) )
  634. {
  635. if ( IpMap.DeleteComputer( iServer ) )
  636. {
  637. fUpdateIpMap = TRUE;
  638. }
  639. else
  640. {
  641. hRes = RETURNCODETOHRESULT( GetLastError() );
  642. }
  643. }
  644. else
  645. {
  646. hRes = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  647. }
  648. break;
  649. case CMD_DEL_IP:
  650. if ( cParam == 1 &&
  651. LocatePublicIp( &IpMap, apszParam[0], &iPublicIp ) )
  652. {
  653. if ( IpMap.DeleteIpPublic( iPublicIp ) )
  654. {
  655. fUpdateIpMap = TRUE;
  656. }
  657. else
  658. {
  659. hRes = RETURNCODETOHRESULT( GetLastError() );
  660. }
  661. }
  662. else
  663. {
  664. hRes = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  665. }
  666. break;
  667. case CMD_DEL_PERFMON:
  668. if ( cParam == 2 &&
  669. LocatePerfCounter( &PerfCounters, apszParam[0], apszParam[1], &iPerfCounter ) )
  670. {
  671. if ( PerfCounters.DeletePerfCounter( iPerfCounter ) )
  672. {
  673. fUpdatePerfCounters = TRUE;
  674. }
  675. else
  676. {
  677. hRes = RETURNCODETOHRESULT( GetLastError() );
  678. }
  679. }
  680. else
  681. {
  682. hRes = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  683. }
  684. break;
  685. #if 0
  686. case CMD_SET_STICKY:
  687. if ( cParam == 1 )
  688. {
  689. dwSticky = _wtoi( apszParam[0] );
  690. fUpdateSticky = TRUE;
  691. }
  692. else
  693. {
  694. hRes = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  695. }
  696. break;
  697. #endif
  698. case CMD_SET_IP:
  699. if ( cParam == 4 &&
  700. LocateServer( &IpMap, apszParam[0], &iServer ) &&
  701. LocatePublicIp( &IpMap, apszParam[1], &iPublicIp ) )
  702. {
  703. if ( IpMap.SetIpPrivate( iServer, iPublicIp, apszParam[2], apszParam[3] ) )
  704. {
  705. fUpdateIpMap = TRUE;
  706. }
  707. else
  708. {
  709. hRes = RETURNCODETOHRESULT( GetLastError() );
  710. }
  711. }
  712. else
  713. {
  714. hRes = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  715. }
  716. break;
  717. case CMD_LIST_IP_ENDPOINTS:
  718. RC_PRINTF( IDS_LBC_IPE, (RC_BUFF) );
  719. for ( iPublicIp = 0 ;
  720. IpEndpoints.EnumIpEndpoint( iPublicIp, &pszPublicIp ) ;
  721. ++iPublicIp )
  722. {
  723. wprintf( L"%-*.*s\t", LEN_IP, LEN_IP, pszPublicIp );
  724. }
  725. wprintf( L"\n");
  726. break;
  727. case CMD_LIST:
  728. RC_PRINTF( IDS_LBC_IPM, (RC_BUFF, LEN_SERVER_NAME, LEN_SERVER_NAME, "") );
  729. for ( iPublicIp = 0 ;
  730. IpMap.EnumIpPublic( iPublicIp, &pszPublicIp, &pszName, &dwSticky, &dwAttr ) ;
  731. ++iPublicIp )
  732. {
  733. wprintf( L"%-*.*s\t", LEN_IP, LEN_IP, pszPublicIp );
  734. }
  735. wprintf( L"\n");
  736. for ( iServer = 0 ;
  737. IpMap.EnumComputer( iServer, &pszServer ) ;
  738. ++iServer )
  739. {
  740. wprintf( L"%-*.*s\t", LEN_SERVER_NAME, LEN_SERVER_NAME, pszServer );
  741. for ( iPublicIp = 0 ;
  742. IpMap.EnumIpPublic( iPublicIp, &pszPublicIp, &pszName, &dwSticky, &dwAttr ) ;
  743. ++iPublicIp )
  744. {
  745. IpMap.GetIpPrivate( iServer, iPublicIp, &pszPrivateIp, &pszName );
  746. wprintf( L"%-*.*s\t", LEN_IP, LEN_IP, pszPrivateIp );
  747. }
  748. wprintf( L"\n");
  749. }
  750. wprintf( L"\n");
  751. RC_PRINTF( IDS_LBC_PM, (RC_BUFF) );
  752. for ( iPerfCounter = 0 ;
  753. PerfCounters.EnumPerfCounter( iPerfCounter, &pszServer, &pszPerfCounter, &dwWeight ) ;
  754. ++iPerfCounter )
  755. {
  756. wprintf( L"%-*.*s%-*.*s\t%u\n",
  757. LEN_SERVER_NAME, LEN_SERVER_NAME, pszServer ? pszServer : L"*",
  758. LEN_PERF, LEN_PERF, pszPerfCounter,
  759. dwWeight );
  760. }
  761. wprintf( L"\n");
  762. #if 0
  763. RC_PRINTF( IDS_LBC_ST, (RC_BUFF, dwSticky) );
  764. #endif
  765. break;
  766. }
  767. // update configuration
  768. if ( SUCCEEDED( hRes ) &&
  769. fUpdateIpMap &&
  770. (xbf.Reset, IpMap.Serialize( &xbf )) )
  771. {
  772. hRes = pIisLb->SetIpList( xbf.GetUsed(), xbf.GetBuff() );
  773. }
  774. if ( SUCCEEDED( hRes ) &&
  775. fUpdatePerfCounters &&
  776. (xbf.Reset, PerfCounters.Serialize( &xbf )) )
  777. {
  778. hRes = pIisLb->SetPerfmonCounters( xbf.GetUsed(), xbf.GetBuff() );
  779. }
  780. #if 0
  781. if ( SUCCEEDED( hRes ) &&
  782. fUpdateSticky )
  783. {
  784. hRes = pIisLb->SetStickyDuration( dwSticky );
  785. }
  786. #endif
  787. pIisLb->Release();
  788. }
  789. if ( FAILED( hRes ) )
  790. {
  791. DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
  792. }
  793. CoUninitialize();
  794. return Status;
  795. }