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

998 lines
22 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. lmoddlg.cpp
  5. Abstract:
  6. Licensing mode dialog.
  7. Author:
  8. Don Ryan (donryan) 28-Feb-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 16-Jan-1996
  13. o Ported to CCF API to add/remove licenses, incl. removing
  14. edit box for number of licenses and replacing with
  15. Add/Remove Licenses buttons.
  16. o Added warning of possible loss when switching license modes.
  17. --*/
  18. #include "stdafx.h"
  19. #include "llsmgr.h"
  20. #include "lmoddlg.h"
  21. #include "psrvdlg.h"
  22. #include "pseatdlg.h"
  23. #include "srvldlg.h"
  24. #include "lviodlg.h"
  25. #include <strsafe.h>
  26. static TCHAR szServerServiceNameNew[] = _T("Windows Server");
  27. static TCHAR szServerServiceNameOld2[] = _T("Windows NT Server");
  28. static TCHAR szServerServiceNameOld[] = _T("File and Print Service");
  29. #ifdef _DEBUG
  30. #undef THIS_FILE
  31. static char BASED_CODE THIS_FILE[] = __FILE__;
  32. #endif
  33. BEGIN_MESSAGE_MAP(CLicensingModeDialog, CDialog)
  34. //{{AFX_MSG_MAP(CLicensingModeDialog)
  35. ON_BN_CLICKED(IDC_MODE_RADIO_PER_SEAT, OnModePerSeat)
  36. ON_BN_CLICKED(IDC_MODE_RADIO_PER_SERVER, OnModePerServer)
  37. ON_EN_UPDATE(IDC_MODE_LICENSES, OnUpdateQuantity)
  38. ON_COMMAND(ID_HELP, OnHelp)
  39. //}}AFX_MSG_MAP
  40. ON_BN_CLICKED(IDC_MODE_ADD_PER_SERVER, OnAddPerServer)
  41. ON_BN_CLICKED(IDC_MODE_REMOVE_PER_SERVER, OnRemovePerServer)
  42. END_MESSAGE_MAP()
  43. CLicensingModeDialog::CLicensingModeDialog(CWnd* pParent /*=NULL*/)
  44. : CDialog(CLicensingModeDialog::IDD, pParent)
  45. /*++
  46. Routine Description:
  47. Constructor for dialog.
  48. Arguments:
  49. pParent - owner window.
  50. Return Values:
  51. None.
  52. --*/
  53. {
  54. //{{AFX_DATA_INIT(CLicensingModeDialog)
  55. m_nLicenses = 0;
  56. m_strPerSeatStatic = _T("");
  57. m_strSupportsStatic = _T("");
  58. //}}AFX_DATA_INIT
  59. m_pService = NULL;
  60. m_bAreCtrlsInitialized = FALSE;
  61. m_fUpdateHint = UPDATE_INFO_NONE;
  62. }
  63. void CLicensingModeDialog::DoDataExchange(CDataExchange* pDX)
  64. /*++
  65. Routine Description:
  66. Called by framework to exchange dialog data.
  67. Arguments:
  68. pDX - data exchange object.
  69. Return Values:
  70. None.
  71. --*/
  72. {
  73. CDialog::DoDataExchange(pDX);
  74. //{{AFX_DATA_MAP(CLicensingModeDialog)
  75. DDX_Control(pDX, IDOK, m_okBtn);
  76. DDX_Control(pDX, IDC_MODE_LICENSES, m_licEdit);
  77. DDX_Text(pDX, IDC_MODE_LICENSES, m_nLicenses);
  78. DDV_MinMaxDWord(pDX, m_nLicenses, 0, 999999);
  79. DDX_Text(pDX, IDC_MODE_STATIC_PER_SEAT, m_strPerSeatStatic);
  80. DDX_Text(pDX, IDC_MODE_STATIC_SUPPORTS, m_strSupportsStatic);
  81. DDX_Control(pDX, IDC_MODE_RADIO_PER_SEAT, m_perSeatBtn);
  82. DDX_Control(pDX, IDC_MODE_RADIO_PER_SERVER, m_perServerBtn);
  83. //}}AFX_DATA_MAP
  84. DDX_Control(pDX, IDC_MODE_ADD_PER_SERVER, m_addPerServerBtn);
  85. DDX_Control(pDX, IDC_MODE_REMOVE_PER_SERVER, m_removePerServerBtn);
  86. }
  87. void CLicensingModeDialog::InitDialog(CService* pService)
  88. /*++
  89. Routine Description:
  90. Initializes dialog.
  91. Arguments:
  92. pService - service object.
  93. Return Values:
  94. None.
  95. --*/
  96. {
  97. VALIDATE_OBJECT(pService, CService);
  98. m_pService = pService;
  99. BSTR bstrDisplayName = m_pService->GetDisplayName();
  100. m_strServiceName = bstrDisplayName;
  101. SysFreeString(bstrDisplayName);
  102. }
  103. void CLicensingModeDialog::InitCtrls()
  104. /*++
  105. Routine Description:
  106. Initializes dialog controls.
  107. Arguments:
  108. None.
  109. Return Values:
  110. None.
  111. --*/
  112. {
  113. m_licEdit.LimitText(6);
  114. if (m_pService->IsPerServer())
  115. {
  116. OnModePerServer();
  117. }
  118. else
  119. {
  120. OnModePerSeat();
  121. }
  122. m_bAreCtrlsInitialized = TRUE;
  123. }
  124. BOOL CLicensingModeDialog::OnInitDialog()
  125. /*++
  126. Routine Description:
  127. Message handler for WM_INITDIALOG.
  128. Arguments:
  129. None.
  130. Return Values:
  131. Returns false if focus set manually.
  132. --*/
  133. {
  134. AfxFormatString1(
  135. m_strPerSeatStatic,
  136. IDS_LICENSING_MODE_1,
  137. m_strServiceName
  138. );
  139. AfxFormatString1(
  140. m_strSupportsStatic,
  141. IDS_LICENSING_MODE_2,
  142. m_strServiceName
  143. );
  144. CDialog::OnInitDialog();
  145. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  146. return TRUE;
  147. }
  148. void CLicensingModeDialog::OnModePerSeat()
  149. /*++
  150. Routine Description:
  151. Changing mode to per seat.
  152. Arguments:
  153. None.
  154. Return Values:
  155. None.
  156. --*/
  157. {
  158. m_perSeatBtn.SetCheck(1);
  159. m_perServerBtn.SetCheck(0);
  160. ::SafeEnableWindow(&m_addPerServerBtn, &m_okBtn, CDialog::GetFocus(), FALSE);
  161. ::SafeEnableWindow(&m_removePerServerBtn, &m_okBtn, CDialog::GetFocus(), FALSE);
  162. m_licEdit.Clear();
  163. if (m_pService->IsPerServer())
  164. {
  165. if (m_pService->IsReadOnly())
  166. {
  167. CLicensingViolationDialog vioDlg;
  168. if (vioDlg.DoModal() != IDOK)
  169. {
  170. OnModePerServer();
  171. return; // bail...
  172. }
  173. }
  174. if ( ( 0 != GetDlgItemInt( IDC_MODE_LICENSES, NULL, FALSE ) )
  175. && ( IDYES != AfxMessageBox( IDP_CONFIRM_TO_PER_SEAT, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 ) ) )
  176. {
  177. OnModePerServer();
  178. return; // bail...
  179. }
  180. }
  181. }
  182. void CLicensingModeDialog::OnModePerServer()
  183. /*++
  184. Routine Description:
  185. Changing mode to per server.
  186. Arguments:
  187. None.
  188. Return Values:
  189. None.
  190. --*/
  191. {
  192. m_perSeatBtn.SetCheck(0);
  193. m_perServerBtn.SetCheck(1);
  194. ::SafeEnableWindow(&m_addPerServerBtn, &m_okBtn, CDialog::GetFocus(), TRUE);
  195. ::SafeEnableWindow(&m_removePerServerBtn, &m_okBtn, CDialog::GetFocus(), TRUE);
  196. UpdatePerServerLicenses();
  197. if (!m_pService->IsPerServer())
  198. {
  199. if (m_pService->IsReadOnly())
  200. {
  201. CLicensingViolationDialog vioDlg;
  202. if (vioDlg.DoModal() != IDOK)
  203. {
  204. OnModePerSeat();
  205. return; // bail...
  206. }
  207. }
  208. if ( IDYES != AfxMessageBox( IDP_CONFIRM_TO_PER_SERVER, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 ) )
  209. {
  210. OnModePerSeat();
  211. return; // bail...
  212. }
  213. }
  214. }
  215. void CLicensingModeDialog::OnOK()
  216. /*++
  217. Routine Description:
  218. Update registry.
  219. Arguments:
  220. None.
  221. Return Values:
  222. None.
  223. --*/
  224. {
  225. BOOL bUpdateRegistry = TRUE;
  226. if (m_perSeatBtn.GetCheck())
  227. {
  228. if (m_pService->IsPerServer())
  229. {
  230. CPerSeatLicensingDialog perSeatDlg;
  231. perSeatDlg.m_strProduct = m_strServiceName;
  232. if (perSeatDlg.DoModal() != IDOK)
  233. return; // bail...
  234. }
  235. else
  236. {
  237. bUpdateRegistry = FALSE;
  238. }
  239. }
  240. else if (m_perServerBtn.GetCheck())
  241. {
  242. if (!UpdateData(TRUE))
  243. return; // bail...
  244. if (!m_pService->IsPerServer())
  245. {
  246. if (!m_nLicenses &&
  247. (!m_strServiceName.CompareNoCase(szServerServiceNameNew) ||
  248. !m_strServiceName.CompareNoCase(szServerServiceNameOld2) ||
  249. !m_strServiceName.CompareNoCase(szServerServiceNameOld)))
  250. {
  251. CServerLicensingDialog srvlDlg;
  252. if (srvlDlg.DoModal() != IDOK)
  253. return; // bail...
  254. }
  255. else
  256. {
  257. CString strLicenses;
  258. CPerServerLicensingDialog perServerDlg;
  259. perServerDlg.m_strProduct = m_strServiceName;
  260. strLicenses.Format(_T("%ld"), m_nLicenses);
  261. perServerDlg.m_strLicenses = strLicenses;
  262. if (perServerDlg.DoModal() != IDOK)
  263. return; // bail...
  264. }
  265. }
  266. else
  267. {
  268. bUpdateRegistry = FALSE;
  269. }
  270. }
  271. if (bUpdateRegistry)
  272. {
  273. long Status;
  274. #ifdef CONFIG_THROUGH_REGISTRY
  275. DWORD dwValue;
  276. BOOL bIsRegistryUpdated = FALSE;
  277. HKEY hkeyService = m_pService->GetRegKey();
  278. dwValue = (m_perSeatBtn.GetCheck() || (m_perServerBtn.GetCheck() != m_pService->IsPerServer())) ? 0x1 : 0x0;
  279. Status = RegSetValueEx(
  280. hkeyService,
  281. REG_VALUE_FLIP,
  282. 0,
  283. REG_DWORD,
  284. (PBYTE)&dwValue,
  285. sizeof(DWORD)
  286. );
  287. if (Status == ERROR_SUCCESS)
  288. {
  289. m_fUpdateHint |= UPDATE_LICENSE_MODE; // update...
  290. m_pService->m_bIsReadOnly = (dwValue == 0x1); // update...
  291. dwValue = m_perSeatBtn.GetCheck() ? 0x0 : 0x1;
  292. Status = RegSetValueEx(
  293. hkeyService,
  294. REG_VALUE_MODE,
  295. 0,
  296. REG_DWORD,
  297. (PBYTE)&dwValue,
  298. sizeof(DWORD)
  299. );
  300. if (Status == ERROR_SUCCESS)
  301. {
  302. m_pService->m_bIsPerServer = (dwValue == 0x1); // update...
  303. bIsRegistryUpdated = TRUE;
  304. }
  305. }
  306. if (hkeyService)
  307. {
  308. RegCloseKey(hkeyService);
  309. }
  310. if (!bIsRegistryUpdated)
  311. {
  312. theApp.DisplayStatus(::GetLastError());
  313. return; // bail...
  314. }
  315. #else
  316. CServer* pServer = (CServer*)MKOBJ(m_pService->GetParent());
  317. if ( pServer && pServer->ConnectLls() ) // JonN 5/5/00 PREFIX 112122
  318. {
  319. BSTR pKeyName = m_pService->GetName();
  320. if ( NULL == pKeyName )
  321. {
  322. Status = STATUS_NO_MEMORY;
  323. }
  324. else
  325. {
  326. PLLS_LOCAL_SERVICE_INFO_0 pServiceInfo = NULL;
  327. Status = ::LlsLocalServiceInfoGet( pServer->GetLlsHandle(), pKeyName, 0, (LPBYTE *) &pServiceInfo );
  328. if ( NT_SUCCESS( Status ) )
  329. {
  330. pServiceInfo->FlipAllow = (m_perSeatBtn.GetCheck() || (m_perServerBtn.GetCheck() != m_pService->IsPerServer())) ? 0x1 : 0x0;
  331. pServiceInfo->Mode = m_perSeatBtn.GetCheck() ? 0x0 : 0x1;
  332. Status = ::LlsLocalServiceInfoSet( pServer->GetLlsHandle(), pKeyName, 0, (LPBYTE) pServiceInfo );
  333. if ( NT_SUCCESS( Status ) )
  334. {
  335. m_fUpdateHint |= UPDATE_LICENSE_MODE; // update...
  336. m_pService->m_bIsReadOnly = ( 0x1 == pServiceInfo->FlipAllow ); // update...
  337. m_pService->m_bIsPerServer = ( 0x1 == pServiceInfo->Mode ); // update...
  338. }
  339. ::LlsFreeMemory( pServiceInfo->KeyName );
  340. ::LlsFreeMemory( pServiceInfo->DisplayName );
  341. ::LlsFreeMemory( pServiceInfo->FamilyDisplayName );
  342. ::LlsFreeMemory( pServiceInfo );
  343. }
  344. if ( IsConnectionDropped( Status ) )
  345. {
  346. pServer->DisconnectLls();
  347. }
  348. SysFreeString( pKeyName );
  349. }
  350. }
  351. else
  352. {
  353. Status = LlsGetLastStatus();
  354. }
  355. LlsSetLastStatus( Status );
  356. if ( !NT_SUCCESS( Status ) )
  357. {
  358. theApp.DisplayStatus( Status );
  359. return; // bail...
  360. }
  361. #endif
  362. }
  363. EndDialog(IDOK);
  364. return;
  365. }
  366. void CLicensingModeDialog::OnCancel()
  367. /*++
  368. Routine Description:
  369. Update registry.
  370. Arguments:
  371. None.
  372. Return Values:
  373. None.
  374. --*/
  375. {
  376. if (m_nLicenses > (LONG) 999999)
  377. {
  378. UpdateData( TRUE );
  379. }
  380. else
  381. {
  382. EndDialog( 0 );
  383. }
  384. return;
  385. }
  386. BOOL CLicensingModeDialog::OnCommand(WPARAM wParam, LPARAM lParam)
  387. /*++
  388. Routine Description:
  389. Message handler for WM_COMMAND.
  390. Arguments:
  391. wParam - message specific.
  392. lParam - message specific.
  393. Return Values:
  394. Returns true if message processed.
  395. --*/
  396. {
  397. if (wParam == ID_INIT_CTRLS)
  398. {
  399. if (!m_bAreCtrlsInitialized)
  400. {
  401. InitCtrls();
  402. }
  403. return TRUE; // processed...
  404. }
  405. return CDialog::OnCommand(wParam, lParam);
  406. }
  407. void CLicensingModeDialog::OnDeltaPosSpin(NMHDR* pNMHDR, LRESULT* pResult)
  408. /*++
  409. Routine Description:
  410. Notification handler for UDN_DELTAPOS.
  411. Arguments:
  412. pNMHDR - notification header.
  413. pResult - return code.
  414. Return Values:
  415. None.
  416. --*/
  417. {
  418. UpdateData(TRUE); // get data
  419. m_nLicenses += ((NM_UPDOWN*)pNMHDR)->iDelta;
  420. if (m_nLicenses < 0)
  421. {
  422. m_nLicenses = 0;
  423. ::MessageBeep(MB_OK);
  424. }
  425. else if (m_nLicenses > 999999)
  426. {
  427. m_nLicenses = 999999;
  428. ::MessageBeep(MB_OK);
  429. }
  430. UpdateData(FALSE); // set data
  431. *pResult = 1; // handle ourselves...
  432. }
  433. void CLicensingModeDialog::OnUpdateQuantity()
  434. /*++
  435. Routine Description:
  436. Message handler for EN_UPDATE.
  437. Arguments:
  438. None.
  439. Return Values:
  440. None.
  441. --*/
  442. {
  443. if (m_licEdit.IsWindowEnabled())
  444. {
  445. long nLicensesOld = m_nLicenses;
  446. if (!UpdateData(TRUE))
  447. {
  448. m_nLicenses = nLicensesOld;
  449. UpdateData(FALSE);
  450. m_licEdit.SetFocus();
  451. m_licEdit.SetSel(0,-1);
  452. ::MessageBeep(MB_OK);
  453. }
  454. }
  455. }
  456. void CLicensingModeDialog::OnHelp()
  457. /*++
  458. Routine Description:
  459. Help button support.
  460. Arguments:
  461. None.
  462. Return Values:
  463. None.
  464. --*/
  465. {
  466. CDialog::OnCommandHelp(0, 0L);
  467. }
  468. void CLicensingModeDialog::OnAddPerServer()
  469. /*++
  470. Routine Description:
  471. Add per server licenses button support.
  472. Arguments:
  473. None.
  474. Return Values:
  475. None.
  476. --*/
  477. {
  478. HRESULT hr;
  479. size_t cch1, cch2;
  480. CServer* pServer = (CServer*)MKOBJ(m_pService->GetParent());
  481. BSTR pszUniServerName = pServer->GetName();
  482. BSTR pszUniProductName = m_pService->GetDisplayName();
  483. if ( ( NULL == pszUniServerName ) || ( NULL == pszUniProductName ) )
  484. {
  485. theApp.DisplayStatus( STATUS_NO_MEMORY );
  486. }
  487. else
  488. {
  489. cch1 = 1 + lstrlen( pszUniServerName );
  490. cch2 = 1 + lstrlen( pszUniProductName );
  491. LPSTR pszAscServerName = (LPSTR) LocalAlloc( LMEM_FIXED, cch1 );
  492. LPSTR pszAscProductName = (LPSTR) LocalAlloc( LMEM_FIXED, cch2 );
  493. if ( ( NULL == pszAscServerName ) || ( NULL == pszAscProductName ) )
  494. {
  495. theApp.DisplayStatus( STATUS_NO_MEMORY );
  496. }
  497. else
  498. {
  499. hr = StringCchPrintfA( pszAscServerName, cch1, "%ls", pszUniServerName );
  500. ASSERT(SUCCEEDED(hr));
  501. hr = StringCchPrintfA( pszAscProductName, cch2, "%ls", pszUniProductName );
  502. ASSERT(SUCCEEDED(hr));
  503. DWORD dwError = CCFCertificateEnterUI( m_hWnd, pszAscServerName, pszAscProductName, "Microsoft", CCF_ENTER_FLAG_PER_SERVER_ONLY, NULL );
  504. if ( ERROR_SUCCESS == dwError )
  505. {
  506. m_fUpdateHint |= UPDATE_INFO_SERVICES | UPDATE_INFO_PRODUCTS; // update...
  507. UpdatePerServerLicenses();
  508. }
  509. }
  510. if ( NULL != pszAscServerName )
  511. {
  512. LocalFree( pszAscServerName );
  513. }
  514. if ( NULL != pszAscProductName )
  515. {
  516. LocalFree( pszAscProductName );
  517. }
  518. }
  519. if ( NULL != pszUniServerName )
  520. {
  521. SysFreeString( pszUniServerName );
  522. }
  523. if ( NULL != pszUniProductName )
  524. {
  525. SysFreeString( pszUniProductName );
  526. }
  527. }
  528. void CLicensingModeDialog::OnRemovePerServer()
  529. /*++
  530. Routine Description:
  531. Remove per server licenses button support.
  532. Arguments:
  533. None.
  534. Return Values:
  535. None.
  536. --*/
  537. {
  538. HRESULT hr;
  539. size_t cch1, cch2;
  540. CServer* pServer = (CServer*)MKOBJ(m_pService->GetParent());
  541. BSTR pszUniServerName = pServer->GetName();
  542. BSTR pszUniProductName = m_pService->GetDisplayName();
  543. if ( ( NULL == pszUniServerName ) || ( NULL == pszUniProductName ) )
  544. {
  545. theApp.DisplayStatus( STATUS_NO_MEMORY );
  546. }
  547. else
  548. {
  549. cch1 = 1 + lstrlen( pszUniServerName );
  550. cch2 = 1 + lstrlen( pszUniProductName );
  551. LPSTR pszAscServerName = (LPSTR) LocalAlloc( LMEM_FIXED, cch1 );
  552. LPSTR pszAscProductName = (LPSTR) LocalAlloc( LMEM_FIXED, cch2 );
  553. if ( ( NULL == pszAscServerName ) || ( NULL == pszAscProductName ) )
  554. {
  555. theApp.DisplayStatus( STATUS_NO_MEMORY );
  556. }
  557. else
  558. {
  559. hr = StringCchPrintfA( pszAscServerName, cch1, "%ls", pszUniServerName );
  560. ASSERT(SUCCEEDED(hr));
  561. hr = StringCchPrintfA( pszAscProductName, cch2, "%ls", pszUniProductName );
  562. ASSERT(SUCCEEDED(hr));
  563. CCFCertificateRemoveUI( m_hWnd, pszAscServerName, pszAscProductName, "Microsoft", NULL, NULL );
  564. m_fUpdateHint |= UPDATE_INFO_SERVERS | UPDATE_INFO_SERVICES | UPDATE_LICENSE_DELETED; // update...
  565. UpdatePerServerLicenses();
  566. }
  567. if ( NULL != pszAscServerName ) LocalFree( pszAscServerName );
  568. if ( NULL != pszAscProductName ) LocalFree( pszAscProductName );
  569. }
  570. if ( NULL != pszUniServerName ) SysFreeString( pszUniServerName );
  571. if ( NULL != pszUniProductName ) SysFreeString( pszUniProductName );
  572. }
  573. void CLicensingModeDialog::UpdatePerServerLicenses()
  574. /*++
  575. Routine Description:
  576. Update the concurrent limit setting from the registry.
  577. Arguments:
  578. None.
  579. Return Values:
  580. None.
  581. --*/
  582. {
  583. HRESULT hr;
  584. size_t cch;
  585. BeginWaitCursor();
  586. CServer* pServer = (CServer*)MKOBJ(m_pService->GetParent());
  587. if ( pServer == NULL )
  588. {
  589. theApp.DisplayStatus( STATUS_NO_MEMORY );
  590. return;
  591. }
  592. BSTR pszUniServerName = pServer->GetName();
  593. BSTR pszUniProductName = m_pService->GetDisplayName();
  594. if ( ( NULL == pszUniServerName ) || ( NULL == pszUniProductName ) )
  595. {
  596. theApp.DisplayStatus( STATUS_NO_MEMORY );
  597. }
  598. else
  599. {
  600. cch = 3 + lstrlen( pszUniServerName );
  601. LPTSTR pszUniNetServerName = (LPTSTR) LocalAlloc( LMEM_FIXED, sizeof( TCHAR) * cch );
  602. if ( NULL == pszUniNetServerName )
  603. {
  604. theApp.DisplayStatus( STATUS_NO_MEMORY );
  605. }
  606. else
  607. {
  608. hr = StringCchPrintf( pszUniNetServerName, cch, TEXT("%ls%ls"), (TEXT('\\') == *pszUniServerName) ? TEXT("") : TEXT("\\\\"), pszUniServerName );
  609. ASSERT(SUCCEEDED(hr));
  610. LLS_HANDLE hLls;
  611. DWORD dwError = LlsConnect( pszUniNetServerName, &hLls );
  612. if ( ERROR_SUCCESS == dwError )
  613. {
  614. DWORD dwConcurrentLimit;
  615. dwError = LlsProductLicensesGet( hLls, pszUniProductName, LLS_LICENSE_MODE_PER_SERVER, &dwConcurrentLimit );
  616. LlsClose( hLls );
  617. if ( ERROR_SUCCESS == dwError )
  618. {
  619. m_pService->m_lPerServerLimit = dwConcurrentLimit;
  620. }
  621. }
  622. if ( ERROR_SUCCESS != dwError )
  623. {
  624. #ifdef CONFIG_THROUGH_REGISTRY
  625. HKEY hkeyService = m_pService->GetRegKey();
  626. DWORD dwConcurrentLimit;
  627. DWORD dwType;
  628. DWORD cb = sizeof( dwConcurrentLimit );
  629. DWORD dwError = RegQueryValueEx( hkeyService, REG_VALUE_LIMIT, NULL, &dwType, (LPBYTE) &dwConcurrentLimit, &cb );
  630. ASSERT( ERROR_SUCCESS == dwError );
  631. if ( ERROR_SUCCESS == dwError )
  632. {
  633. m_pService->m_lPerServerLimit = dwConcurrentLimit;
  634. }
  635. RegCloseKey( hkeyService );
  636. #else
  637. NTSTATUS Status;
  638. if ( pServer->ConnectLls() )
  639. {
  640. BSTR pKeyName = m_pService->GetName();
  641. if ( NULL == pKeyName )
  642. {
  643. Status = STATUS_NO_MEMORY;
  644. }
  645. else
  646. {
  647. PLLS_LOCAL_SERVICE_INFO_0 pServiceInfo = NULL;
  648. Status = ::LlsLocalServiceInfoGet( pServer->GetLlsHandle(), pKeyName, 0, (LPBYTE *) &pServiceInfo );
  649. if ( NT_SUCCESS( Status ) )
  650. {
  651. m_pService->m_lPerServerLimit = pServiceInfo->ConcurrentLimit;
  652. ::LlsFreeMemory( pServiceInfo->KeyName );
  653. ::LlsFreeMemory( pServiceInfo->DisplayName );
  654. ::LlsFreeMemory( pServiceInfo->FamilyDisplayName );
  655. ::LlsFreeMemory( pServiceInfo );
  656. }
  657. if ( IsConnectionDropped( Status ) )
  658. {
  659. pServer->DisconnectLls();
  660. }
  661. SysFreeString( pKeyName );
  662. }
  663. }
  664. else
  665. {
  666. Status = LlsGetLastStatus();
  667. }
  668. LlsSetLastStatus( Status );
  669. if ( !NT_SUCCESS( Status ) )
  670. {
  671. theApp.DisplayStatus( Status );
  672. return; // bail...
  673. }
  674. #endif
  675. }
  676. }
  677. if ( NULL != pszUniNetServerName )
  678. {
  679. LocalFree( pszUniNetServerName );
  680. }
  681. }
  682. if ( NULL != pszUniServerName )
  683. {
  684. SysFreeString( pszUniServerName );
  685. }
  686. if ( NULL != pszUniProductName )
  687. {
  688. SysFreeString( pszUniProductName );
  689. }
  690. EndWaitCursor();
  691. m_nLicenses = m_pService->m_lPerServerLimit;
  692. UpdateData(FALSE);
  693. }