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.

1269 lines
25 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. ctlobj.cpp
  5. Abstract:
  6. License controller object implementation.
  7. Author:
  8. Don Ryan (donryan) 27-Dec-1994
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 16-Jan-1996
  13. Added SetLastTargetServer() to Connect() to help isolate server
  14. connection problems. (Bug #2993.)
  15. --*/
  16. #include "stdafx.h"
  17. #include "llsmgr.h"
  18. #include <lm.h>
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char BASED_CODE THIS_FILE[] = __FILE__;
  22. #endif
  23. IMPLEMENT_DYNCREATE(CController, CCmdTarget)
  24. BEGIN_MESSAGE_MAP(CController, CCmdTarget)
  25. //{{AFX_MSG_MAP(CController)
  26. //}}AFX_MSG_MAP
  27. END_MESSAGE_MAP()
  28. BEGIN_DISPATCH_MAP(CController, CCmdTarget)
  29. //{{AFX_DISPATCH_MAP(CController)
  30. DISP_PROPERTY_EX(CController, "Name", GetName, SetNotSupported, VT_BSTR)
  31. DISP_PROPERTY_EX(CController, "Application", GetApplication, SetNotSupported, VT_DISPATCH)
  32. DISP_PROPERTY_EX(CController, "Parent", GetParent, SetNotSupported, VT_DISPATCH)
  33. DISP_PROPERTY_EX(CController, "IsConnected", IsConnected, SetNotSupported, VT_BOOL)
  34. DISP_FUNCTION(CController, "Connect", Connect, VT_BOOL, VTS_VARIANT)
  35. DISP_FUNCTION(CController, "Disconnect", Disconnect, VT_EMPTY, VTS_NONE)
  36. DISP_FUNCTION(CController, "Refresh", Refresh, VT_EMPTY, VTS_NONE)
  37. DISP_PROPERTY_PARAM(CController, "Mappings", GetMappings, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  38. DISP_PROPERTY_PARAM(CController, "Users", GetUsers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  39. DISP_PROPERTY_PARAM(CController, "Licenses", GetLicenses, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  40. DISP_PROPERTY_PARAM(CController, "Products", GetProducts, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  41. DISP_DEFVALUE(CController, "Name")
  42. //}}AFX_DISPATCH_MAP
  43. END_DISPATCH_MAP()
  44. BOOL IsAdminOn(LPTSTR ServerName);
  45. CController::CController()
  46. /*++
  47. Routine Description:
  48. Constructor for license controller object.
  49. Arguments:
  50. None.
  51. Return Values:
  52. None.
  53. --*/
  54. {
  55. EnableAutomation();
  56. m_strName.Empty();
  57. m_pProducts = NULL;
  58. m_pUsers = NULL;
  59. m_pMappings = NULL;
  60. m_pLicenses = NULL;
  61. m_llsHandle = NULL;
  62. m_productArray.RemoveAll();
  63. m_licenseArray.RemoveAll();
  64. m_mappingArray.RemoveAll();
  65. m_userArray.RemoveAll();
  66. m_bProductsRefreshed = FALSE;
  67. m_bLicensesRefreshed = FALSE;
  68. m_bMappingsRefreshed = FALSE;
  69. m_bUsersRefreshed = FALSE;
  70. m_bIsConnected = FALSE;
  71. }
  72. CController::~CController()
  73. /*++
  74. Routine Description:
  75. Destructor for license controller object.
  76. Arguments:
  77. None.
  78. Return Values:
  79. None.
  80. --*/
  81. {
  82. Disconnect();
  83. if (m_pProducts)
  84. m_pProducts->InternalRelease();
  85. if (m_pLicenses)
  86. m_pLicenses->InternalRelease();
  87. if (m_pMappings)
  88. m_pMappings->InternalRelease();
  89. if (m_pUsers)
  90. m_pUsers->InternalRelease();
  91. }
  92. BOOL CController::Connect(const VARIANT FAR& start)
  93. /*++
  94. Routine Description:
  95. Seek out license controller and establish connection.
  96. Arguments:
  97. start - either a server or domain to start searching for
  98. the license controller from.
  99. Return Values:
  100. VT_BOOL.
  101. --*/
  102. {
  103. VARIANT va;
  104. VariantInit(&va);
  105. LPTSTR pControllerName = NULL;
  106. if (!V_ISVOID((VARIANT FAR*)&start))
  107. {
  108. if (start.vt == VT_BSTR)
  109. {
  110. pControllerName = start.bstrVal;
  111. }
  112. else if (SUCCEEDED(VariantChangeType(&va, (VARIANT FAR*)&start, 0, VT_BSTR)))
  113. {
  114. pControllerName = va.bstrVal;
  115. }
  116. else
  117. {
  118. LlsSetLastStatus(STATUS_INVALID_PARAMETER);
  119. return FALSE;
  120. }
  121. }
  122. NTSTATUS NtStatus;
  123. LPVOID llsHandle = NULL;
  124. PLLS_CONNECT_INFO_0 pConnectInfo0 = NULL;
  125. NtStatus = ::LlsEnterpriseServerFind(
  126. pControllerName,
  127. 0,
  128. (LPBYTE*)&pConnectInfo0
  129. );
  130. if (NT_SUCCESS(NtStatus))
  131. {
  132. if (!IsAdminOn( pConnectInfo0->EnterpriseServer ))
  133. {
  134. LlsSetLastStatus(STATUS_ACCESS_DENIED);
  135. return FALSE;
  136. }
  137. LlsSetLastTargetServer( pConnectInfo0->EnterpriseServer );
  138. NtStatus = ::LlsConnect(
  139. pConnectInfo0->EnterpriseServer,
  140. &llsHandle
  141. );
  142. if (NT_SUCCESS(NtStatus))
  143. {
  144. Disconnect();
  145. m_bIsConnected = TRUE;
  146. m_llsHandle = llsHandle;
  147. m_strName = pConnectInfo0->EnterpriseServer;
  148. m_strActiveDomainName = pConnectInfo0->Domain;
  149. m_strName.MakeUpper();
  150. m_strActiveDomainName.MakeUpper();
  151. }
  152. ::LlsFreeMemory(pConnectInfo0);
  153. }
  154. else
  155. {
  156. LlsSetLastTargetServer( TEXT( "" ) );
  157. }
  158. VariantClear(&va);
  159. LlsSetLastStatus(NtStatus);
  160. return NT_SUCCESS(NtStatus);
  161. }
  162. void CController::Disconnect()
  163. /*++
  164. Routine Description:
  165. Closes connection to license controller.
  166. Arguments:
  167. None.
  168. Return Values:
  169. None.
  170. --*/
  171. {
  172. if (m_bIsConnected)
  173. {
  174. LlsClose(m_llsHandle);
  175. m_llsHandle = NULL;
  176. m_bIsConnected = FALSE;
  177. m_strName.Empty();
  178. m_strActiveDomainName.Empty();
  179. ResetLicenses();
  180. ResetProducts();
  181. ResetUsers();
  182. ResetMappings();
  183. }
  184. }
  185. BSTR CController::GetActiveDomainName()
  186. /*++
  187. Routine Description:
  188. Returns the name of the active domain (internal).
  189. Arguments:
  190. None.
  191. Return Values:
  192. VT_BSTR.
  193. --*/
  194. {
  195. return m_strActiveDomainName.AllocSysString();
  196. }
  197. LPDISPATCH CController::GetApplication()
  198. /*++
  199. Routine Description:
  200. Returns the application object.
  201. Arguments:
  202. None.
  203. Return Values:
  204. VT_DISPATCH.
  205. --*/
  206. {
  207. return theApp.GetAppIDispatch();
  208. }
  209. LPDISPATCH CController::GetLicenses(const VARIANT FAR& index)
  210. /*++
  211. Routine Description:
  212. Returns a collection object containing all of the
  213. license agreements recorded on the license controller
  214. or returns an individual license agreement described by
  215. an index into the collection.
  216. Arguments:
  217. index - optional argument that may be a number (VT_I4)
  218. indicating the position within collection.
  219. Return Values:
  220. VT_DISPATCH or VT_EMPTY.
  221. --*/
  222. {
  223. LPDISPATCH lpdispatch = NULL;
  224. if (!m_pLicenses)
  225. {
  226. m_pLicenses = new CLicenses(this, &m_licenseArray);
  227. }
  228. if (m_pLicenses)
  229. {
  230. if (V_ISVOID((VARIANT FAR*)&index))
  231. {
  232. if (RefreshLicenses())
  233. {
  234. lpdispatch = m_pLicenses->GetIDispatch(TRUE);
  235. }
  236. }
  237. else
  238. {
  239. if (m_bLicensesRefreshed)
  240. {
  241. lpdispatch = m_pLicenses->GetItem(index);
  242. }
  243. else if (RefreshLicenses())
  244. {
  245. lpdispatch = m_pLicenses->GetItem(index);
  246. }
  247. }
  248. }
  249. else
  250. {
  251. LlsSetLastStatus( STATUS_NO_MEMORY );
  252. }
  253. return lpdispatch;
  254. }
  255. LPDISPATCH CController::GetMappings(const VARIANT FAR& index)
  256. /*++
  257. Routine Description:
  258. Returns a collection object containing all of the
  259. user/node associations recorded on the license controller
  260. or returns an individual user/node association described by
  261. an index into the collection.
  262. Arguments:
  263. index - optional argument that may be a string (VT_BSTR)
  264. indicating a mapping name or a number (VT_I4) indicating
  265. the position within collection.
  266. Return Values:
  267. VT_DISPATCH or VT_EMPTY.
  268. --*/
  269. {
  270. LPDISPATCH lpdispatch = NULL;
  271. if (!m_pMappings)
  272. {
  273. m_pMappings = new CMappings(this, &m_mappingArray);
  274. }
  275. if (m_pMappings)
  276. {
  277. if (V_ISVOID((VARIANT FAR*)&index))
  278. {
  279. if (RefreshMappings())
  280. {
  281. lpdispatch = m_pMappings->GetIDispatch(TRUE);
  282. }
  283. }
  284. else
  285. {
  286. if (m_bMappingsRefreshed)
  287. {
  288. lpdispatch = m_pMappings->GetItem(index);
  289. }
  290. else if (RefreshMappings())
  291. {
  292. lpdispatch = m_pMappings->GetItem(index);
  293. }
  294. }
  295. }
  296. else
  297. {
  298. LlsSetLastStatus(STATUS_NO_MEMORY);
  299. }
  300. return lpdispatch;
  301. }
  302. BSTR CController::GetName()
  303. /*++
  304. Routine Description:
  305. Returns the name of the license controller.
  306. Arguments:
  307. None.
  308. Return Values:
  309. VT_BSTR.
  310. --*/
  311. {
  312. return m_strName.AllocSysString();
  313. }
  314. LPDISPATCH CController::GetParent()
  315. /*++
  316. Routine Description:
  317. Returns the parent of the object.
  318. Arguments:
  319. None.
  320. Return Values:
  321. VT_DISPATCH.
  322. --*/
  323. {
  324. return GetApplication();
  325. }
  326. LPDISPATCH CController::GetProducts(const VARIANT FAR& index)
  327. /*++
  328. Routine Description:
  329. Returns a collection object containing all of the
  330. registered products replicated to the license controller
  331. or returns an individual product described by an index
  332. into the collection.
  333. Arguments:
  334. index - optional argument that may be a string (VT_BSTR)
  335. indicating a product name or a number (VT_I4) indicating
  336. the position within collection.
  337. Return Values:
  338. VT_DISPATCH or VT_EMPTY.
  339. --*/
  340. {
  341. LPDISPATCH lpdispatch = NULL;
  342. if (!m_pProducts)
  343. {
  344. m_pProducts = new CProducts(this, &m_productArray);
  345. }
  346. if (m_pProducts)
  347. {
  348. if (V_ISVOID((VARIANT FAR*)&index))
  349. {
  350. if (RefreshProducts())
  351. {
  352. lpdispatch = m_pProducts->GetIDispatch(TRUE);
  353. }
  354. }
  355. else
  356. {
  357. if (m_bProductsRefreshed)
  358. {
  359. lpdispatch = m_pProducts->GetItem(index);
  360. }
  361. else if (RefreshProducts())
  362. {
  363. lpdispatch = m_pProducts->GetItem(index);
  364. }
  365. }
  366. }
  367. else
  368. {
  369. LlsSetLastStatus(STATUS_NO_MEMORY);
  370. }
  371. return lpdispatch;
  372. }
  373. LPDISPATCH CController::GetUsers(const VARIANT FAR& index)
  374. /*++
  375. Routine Description:
  376. Returns a collection object containing all of the
  377. registered users replicated to the license controller
  378. or returns an individual user described by an index
  379. into the collection.
  380. Arguments:
  381. index - optional argument that may be a string (VT_BSTR)
  382. indicating a user name or a number (VT_I4) indicating the
  383. position within collection.
  384. Return Values:
  385. VT_DISPATCH or VT_EMPTY.
  386. --*/
  387. {
  388. LPDISPATCH lpdispatch = NULL;
  389. if (!m_pUsers)
  390. {
  391. m_pUsers = new CUsers(this, &m_userArray);
  392. }
  393. if (m_pUsers)
  394. {
  395. if (V_ISVOID((VARIANT FAR*)&index))
  396. {
  397. if (RefreshUsers())
  398. {
  399. lpdispatch = m_pUsers->GetIDispatch(TRUE);
  400. }
  401. }
  402. else
  403. {
  404. if (m_bUsersRefreshed)
  405. {
  406. lpdispatch = m_pUsers->GetItem(index);
  407. }
  408. else if (RefreshUsers())
  409. {
  410. lpdispatch = m_pUsers->GetItem(index);
  411. }
  412. }
  413. }
  414. else
  415. {
  416. LlsSetLastStatus(STATUS_NO_MEMORY);
  417. }
  418. return lpdispatch;
  419. }
  420. BOOL CController::IsConnected()
  421. /*++
  422. Routine Description:
  423. Returns true if a connection has been established.
  424. Arguments:
  425. None.
  426. Return Values:
  427. VT_BOOL.
  428. --*/
  429. {
  430. return m_bIsConnected;
  431. }
  432. void CController::Refresh()
  433. /*++
  434. Routine Description:
  435. Retrieve latest data from license controller.
  436. Arguments:
  437. None.
  438. Return Values:
  439. None.
  440. --*/
  441. {
  442. RefreshProducts();
  443. RefreshUsers();
  444. RefreshMappings();
  445. RefreshLicenses();
  446. }
  447. BOOL CController::RefreshLicenses()
  448. /*++
  449. Routine Description:
  450. Refreshs license object array.
  451. Arguments:
  452. None.
  453. Return Values:
  454. VT_BOOL.
  455. --*/
  456. {
  457. ResetLicenses();
  458. if (!m_bIsConnected)
  459. return TRUE;
  460. NTSTATUS NtStatus;
  461. DWORD ResumeHandle = 0L;
  462. int iLicense = 0;
  463. do
  464. {
  465. DWORD EntriesRead;
  466. DWORD TotalEntries;
  467. LPBYTE ReturnBuffer = NULL;
  468. NtStatus = ::LlsLicenseEnum(
  469. m_llsHandle,
  470. 0,
  471. &ReturnBuffer,
  472. LLS_PREFERRED_LENGTH,
  473. &EntriesRead,
  474. &TotalEntries,
  475. &ResumeHandle
  476. );
  477. if (NtStatus == STATUS_SUCCESS ||
  478. NtStatus == STATUS_MORE_ENTRIES)
  479. {
  480. CLicense* pLicense;
  481. PLLS_LICENSE_INFO_0 pLicenseInfo0;
  482. pLicenseInfo0 = (PLLS_LICENSE_INFO_0)ReturnBuffer;
  483. ASSERT(iLicense == m_licenseArray.GetSize());
  484. m_licenseArray.SetSize(m_licenseArray.GetSize() + EntriesRead);
  485. while (EntriesRead--)
  486. {
  487. pLicense = new CLicense(
  488. this,
  489. pLicenseInfo0->Product,
  490. pLicenseInfo0->Admin,
  491. pLicenseInfo0->Date,
  492. pLicenseInfo0->Quantity,
  493. pLicenseInfo0->Comment
  494. );
  495. m_licenseArray.SetAt(iLicense++, pLicense); // validate later...
  496. #ifndef DISABLE_PER_NODE_ALLOCATION
  497. ::LlsFreeMemory(pLicenseInfo0->Product);
  498. ::LlsFreeMemory(pLicenseInfo0->Admin);
  499. ::LlsFreeMemory(pLicenseInfo0->Comment);
  500. #endif // DISABLE_PER_NODE_ALLOCATION
  501. pLicenseInfo0++;
  502. }
  503. ::LlsFreeMemory(ReturnBuffer);
  504. }
  505. } while (NtStatus == STATUS_MORE_ENTRIES);
  506. LlsSetLastStatus(NtStatus); // called api
  507. if (NT_SUCCESS(NtStatus))
  508. {
  509. m_bLicensesRefreshed = TRUE;
  510. }
  511. else
  512. {
  513. ResetLicenses();
  514. }
  515. return m_bLicensesRefreshed;
  516. }
  517. BOOL CController::RefreshMappings()
  518. /*++
  519. Routine Description:
  520. Refreshs mapping object array.
  521. Arguments:
  522. None.
  523. Return Values:
  524. None.
  525. --*/
  526. {
  527. ResetMappings();
  528. if (!m_bIsConnected)
  529. return TRUE;
  530. NTSTATUS NtStatus;
  531. DWORD ResumeHandle = 0L;
  532. int iMapping = 0;
  533. do
  534. {
  535. DWORD EntriesRead;
  536. DWORD TotalEntries;
  537. LPBYTE ReturnBuffer = NULL;
  538. NtStatus = ::LlsGroupEnum(
  539. m_llsHandle,
  540. 1,
  541. &ReturnBuffer,
  542. LLS_PREFERRED_LENGTH,
  543. &EntriesRead,
  544. &TotalEntries,
  545. &ResumeHandle
  546. );
  547. if (NtStatus == STATUS_SUCCESS ||
  548. NtStatus == STATUS_MORE_ENTRIES)
  549. {
  550. CMapping* pMapping ;
  551. PLLS_GROUP_INFO_1 pMappingInfo1;
  552. pMappingInfo1 = (PLLS_GROUP_INFO_1)ReturnBuffer;
  553. ASSERT(iMapping == m_mappingArray.GetSize());
  554. m_mappingArray.SetSize(m_mappingArray.GetSize() + EntriesRead);
  555. while (EntriesRead--)
  556. {
  557. pMapping = new CMapping(
  558. this,
  559. pMappingInfo1->Name,
  560. pMappingInfo1->Licenses,
  561. pMappingInfo1->Comment
  562. );
  563. m_mappingArray.SetAt(iMapping++, pMapping); // validate later...
  564. #ifndef DISABLE_PER_NODE_ALLOCATION
  565. ::LlsFreeMemory(pMappingInfo1->Name);
  566. ::LlsFreeMemory(pMappingInfo1->Comment);
  567. #endif // DISABLE_PER_NODE_ALLOCATION
  568. pMappingInfo1++;
  569. }
  570. ::LlsFreeMemory(ReturnBuffer);
  571. }
  572. } while (NtStatus == STATUS_MORE_ENTRIES);
  573. LlsSetLastStatus(NtStatus); // called api
  574. if (NT_SUCCESS(NtStatus))
  575. {
  576. m_bMappingsRefreshed = TRUE;
  577. }
  578. else
  579. {
  580. ResetMappings();
  581. }
  582. return m_bMappingsRefreshed;
  583. }
  584. BOOL CController::RefreshProducts()
  585. /*++
  586. Routine Description:
  587. Refreshs product object array.
  588. Arguments:
  589. None.
  590. Return Values:
  591. None.
  592. --*/
  593. {
  594. ResetProducts();
  595. if (!m_bIsConnected)
  596. return TRUE;
  597. NTSTATUS NtStatus;
  598. DWORD ResumeHandle = 0L;
  599. int iProduct = 0;
  600. do
  601. {
  602. DWORD EntriesRead;
  603. DWORD TotalEntries;
  604. LPBYTE ReturnBuffer = NULL;
  605. NtStatus = ::LlsProductEnum(
  606. m_llsHandle,
  607. 1,
  608. &ReturnBuffer,
  609. LLS_PREFERRED_LENGTH,
  610. &EntriesRead,
  611. &TotalEntries,
  612. &ResumeHandle
  613. );
  614. if (NtStatus == STATUS_SUCCESS ||
  615. NtStatus == STATUS_MORE_ENTRIES)
  616. {
  617. CProduct* pProduct;
  618. PLLS_PRODUCT_INFO_1 pProductInfo1;
  619. pProductInfo1 = (PLLS_PRODUCT_INFO_1)ReturnBuffer;
  620. ASSERT(iProduct == m_productArray.GetSize());
  621. m_productArray.SetSize(m_productArray.GetSize() + EntriesRead);
  622. while (EntriesRead--)
  623. {
  624. pProduct = new CProduct(
  625. this,
  626. pProductInfo1->Product,
  627. pProductInfo1->Purchased,
  628. pProductInfo1->InUse,
  629. pProductInfo1->ConcurrentTotal,
  630. pProductInfo1->HighMark
  631. );
  632. m_productArray.SetAt(iProduct++, pProduct); // validate later...
  633. #ifndef DISABLE_PER_NODE_ALLOCATION
  634. ::LlsFreeMemory(pProductInfo1->Product);
  635. #endif // DISABLE_PER_NODE_ALLOCATION
  636. pProductInfo1++;
  637. }
  638. ::LlsFreeMemory(ReturnBuffer);
  639. }
  640. } while (NtStatus == STATUS_MORE_ENTRIES);
  641. LlsSetLastStatus(NtStatus);
  642. if (NT_SUCCESS(NtStatus))
  643. {
  644. m_bProductsRefreshed = TRUE;
  645. }
  646. else
  647. {
  648. ResetProducts();
  649. }
  650. return m_bProductsRefreshed;
  651. }
  652. BOOL CController::RefreshUsers()
  653. /*++
  654. Routine Description:
  655. Refreshs user object array.
  656. Arguments:
  657. None.
  658. Return Values:
  659. None.
  660. --*/
  661. {
  662. ResetUsers();
  663. if (!m_bIsConnected)
  664. return TRUE;
  665. NTSTATUS NtStatus;
  666. DWORD ResumeHandle = 0L;
  667. int iUser = 0;
  668. do
  669. {
  670. DWORD EntriesRead;
  671. DWORD TotalEntries;
  672. LPBYTE ReturnBuffer = NULL;
  673. NtStatus = ::LlsUserEnum(
  674. m_llsHandle,
  675. 2,
  676. &ReturnBuffer,
  677. LLS_PREFERRED_LENGTH,
  678. &EntriesRead,
  679. &TotalEntries,
  680. &ResumeHandle
  681. );
  682. if (NtStatus == STATUS_SUCCESS ||
  683. NtStatus == STATUS_MORE_ENTRIES)
  684. {
  685. CUser* pUser;
  686. PLLS_USER_INFO_2 pUserInfo2;
  687. pUserInfo2 = (PLLS_USER_INFO_2)ReturnBuffer;
  688. ASSERT(iUser == m_userArray.GetSize());
  689. m_userArray.SetSize(m_userArray.GetSize() + EntriesRead);
  690. while (EntriesRead--)
  691. {
  692. pUser = new CUser(
  693. this,
  694. pUserInfo2->Name,
  695. pUserInfo2->Flags,
  696. pUserInfo2->Licensed,
  697. pUserInfo2->UnLicensed,
  698. pUserInfo2->Group,
  699. pUserInfo2->Products
  700. );
  701. m_userArray.SetAt(iUser++, pUser); // validate later...
  702. #ifndef DISABLE_PER_NODE_ALLOCATION
  703. ::LlsFreeMemory(pUserInfo2->Name);
  704. ::LlsFreeMemory(pUserInfo2->Group);
  705. ::LlsFreeMemory(pUserInfo2->Products);
  706. #endif // DISABLE_PER_NODE_ALLOCATION
  707. pUserInfo2++;
  708. }
  709. ::LlsFreeMemory(ReturnBuffer);
  710. }
  711. } while (NtStatus == STATUS_MORE_ENTRIES);
  712. LlsSetLastStatus(NtStatus); // called api
  713. if (NT_SUCCESS(NtStatus))
  714. {
  715. m_bUsersRefreshed = TRUE;
  716. }
  717. else
  718. {
  719. ResetUsers();
  720. }
  721. return m_bUsersRefreshed;
  722. }
  723. void CController::ResetLicenses()
  724. /*++
  725. Routine Description:
  726. Resets license object array.
  727. Arguments:
  728. None.
  729. Return Values:
  730. None.
  731. --*/
  732. {
  733. CLicense* pLicense;
  734. INT_PTR iLicense = m_licenseArray.GetSize();
  735. while (iLicense--)
  736. {
  737. pLicense = (CLicense*)m_licenseArray[iLicense];
  738. if (NULL != pLicense)
  739. {
  740. ASSERT(pLicense->IsKindOf(RUNTIME_CLASS(CLicense)));
  741. pLicense->InternalRelease();
  742. }
  743. }
  744. m_licenseArray.RemoveAll();
  745. m_bLicensesRefreshed = FALSE;
  746. }
  747. void CController::ResetMappings()
  748. /*++
  749. Routine Description:
  750. Resets mapping object array.
  751. Arguments:
  752. None.
  753. Return Values:
  754. None.
  755. --*/
  756. {
  757. CMapping* pMapping;
  758. INT_PTR iMapping = m_mappingArray.GetSize();
  759. while (iMapping--)
  760. {
  761. pMapping = (CMapping*)m_mappingArray[iMapping];
  762. if (NULL != pMapping)
  763. {
  764. ASSERT(pMapping->IsKindOf(RUNTIME_CLASS(CMapping)));
  765. pMapping->InternalRelease();
  766. }
  767. }
  768. m_mappingArray.RemoveAll();
  769. m_bMappingsRefreshed = FALSE;
  770. }
  771. void CController::ResetProducts()
  772. /*++
  773. Routine Description:
  774. Resets product object array.
  775. Arguments:
  776. None.
  777. Return Values:
  778. None.
  779. --*/
  780. {
  781. CProduct* pProduct;
  782. INT_PTR iProduct = m_productArray.GetSize();
  783. while (iProduct--)
  784. {
  785. pProduct = (CProduct*)m_productArray[iProduct];
  786. if (NULL != pProduct)
  787. {
  788. ASSERT(pProduct->IsKindOf(RUNTIME_CLASS(CProduct)));
  789. pProduct->InternalRelease();
  790. }
  791. }
  792. m_productArray.RemoveAll();
  793. m_bProductsRefreshed = FALSE;
  794. }
  795. void CController::ResetUsers()
  796. /*++
  797. Routine Description:
  798. Resets user object array.
  799. Arguments:
  800. None.
  801. Return Values:
  802. None.
  803. --*/
  804. {
  805. CUser* pUser;
  806. INT_PTR iUser = m_userArray.GetSize();
  807. while (iUser--)
  808. {
  809. pUser = (CUser*)m_userArray[iUser];
  810. if (NULL != pUser)
  811. {
  812. ASSERT(pUser->IsKindOf(RUNTIME_CLASS(CUser)));
  813. pUser->InternalRelease();
  814. }
  815. }
  816. m_userArray.RemoveAll();
  817. m_bUsersRefreshed = FALSE;
  818. }
  819. BOOL IsAdminOn(LPTSTR ServerName)
  820. /*++
  821. Routine Description:
  822. Checks for Administrative privilege by attempting to connect to the
  823. ADMIN$ share on ServerName.
  824. Arguments:
  825. ServerName - machine with which to attempt a connection
  826. Return Values:
  827. TRUE if successful, FALSE otherwise.
  828. --*/
  829. {
  830. BOOL bIsAdmin = TRUE;
  831. CString strNetShareName;
  832. CString strServerName = ServerName;
  833. strNetShareName = strServerName + TEXT( "\\ADMIN$" );
  834. if ( strNetShareName.Left(2).Compare( TEXT( "\\\\" ) ) )
  835. {
  836. strNetShareName = TEXT( "\\\\" ) + strNetShareName;
  837. }
  838. NET_API_STATUS NetStatus;
  839. USE_INFO_1 UseInfo;
  840. DWORD dwErrorParm;
  841. ZeroMemory( &UseInfo, sizeof( UseInfo ) );
  842. UseInfo.ui1_remote = MKSTR( strNetShareName );
  843. NetStatus = NetUseAdd( NULL, 1, (LPBYTE) &UseInfo, &dwErrorParm );
  844. switch ( NetStatus )
  845. {
  846. case NERR_Success:
  847. NetUseDel( NULL, MKSTR(strNetShareName), 0 );
  848. // fall through
  849. case ERROR_BAD_NETPATH:
  850. case ERROR_BAD_NET_NAME:
  851. case NERR_WkstaNotStarted:
  852. case NERR_NetNotStarted:
  853. case RPC_S_UNKNOWN_IF:
  854. case RPC_S_SERVER_UNAVAILABLE:
  855. // On network errors, go ahead and return TRUE. Let the License
  856. // APIs fail later if there really is a problem. The machine may
  857. // be standalone, or may not have networking installed.
  858. bIsAdmin = TRUE;
  859. break;
  860. default:
  861. // If we get here, the problem was most likely security related.
  862. bIsAdmin = FALSE;
  863. break;
  864. }
  865. return bIsAdmin;
  866. }