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.

599 lines
10 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. usrobj.cpp
  5. Abstract:
  6. User object implementation.
  7. Author:
  8. Don Ryan (donryan) 04-Jan-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 16-Jan-1996
  13. o Modified m_bIsValid and m_bIsBackOffice in constructor to fix
  14. comparison problem in CUserPropertyPageProducts.
  15. ((a != FALSE) && (b != FALSE) does not imply (a == b).)
  16. --*/
  17. #include "stdafx.h"
  18. #include "llsmgr.h"
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char BASED_CODE THIS_FILE[] = __FILE__;
  22. #endif
  23. IMPLEMENT_DYNCREATE(CUser, CCmdTarget)
  24. BEGIN_MESSAGE_MAP(CUser, CCmdTarget)
  25. //{{AFX_MSG_MAP(CUser)
  26. // NOTE - the ClassWizard will add and remove mapping macros here.
  27. //}}AFX_MSG_MAP
  28. END_MESSAGE_MAP()
  29. BEGIN_DISPATCH_MAP(CUser, CCmdTarget)
  30. //{{AFX_DISPATCH_MAP(CUser)
  31. DISP_PROPERTY_EX(CUser, "Application", GetApplication, SetNotSupported, VT_DISPATCH)
  32. DISP_PROPERTY_EX(CUser, "InUse", GetInUse, SetNotSupported, VT_I4)
  33. DISP_PROPERTY_EX(CUser, "Name", GetName, SetNotSupported, VT_BSTR)
  34. DISP_PROPERTY_EX(CUser, "Parent", GetParent, SetNotSupported, VT_DISPATCH)
  35. DISP_PROPERTY_EX(CUser, "Mapping", GetMapping, SetNotSupported, VT_BSTR)
  36. DISP_PROPERTY_EX(CUser, "IsMapped", IsMapped, SetNotSupported, VT_BOOL)
  37. DISP_PROPERTY_EX(CUser, "Unlicensed", GetUnlicensed, SetNotSupported, VT_I4)
  38. DISP_PROPERTY_PARAM(CUser, "Statistics", GetStatistics, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  39. DISP_DEFVALUE(CUser, "Name")
  40. //}}AFX_DISPATCH_MAP
  41. END_DISPATCH_MAP()
  42. CUser::CUser(
  43. CCmdTarget* pParent,
  44. LPCTSTR pName,
  45. DWORD dwFlags,
  46. long lInUse,
  47. long lUnlicensed,
  48. LPCTSTR pMapping,
  49. LPCTSTR pProducts // blah...
  50. )
  51. /*++
  52. Routine Description:
  53. Constructor for user object.
  54. Arguments:
  55. pParent - creator of object.
  56. pName - name of user.
  57. dwFlags - details about user.
  58. lInUse - number of licenses consumed by user (legally).
  59. lUnicensed - number of licenses consumed by user (illegally).
  60. pMapping - license group (if member).
  61. pProducts - shorthand list of products.
  62. Return Values:
  63. None.
  64. --*/
  65. {
  66. EnableAutomation();
  67. #ifdef ENABLE_PARENT_CHECK
  68. ASSERT(pParent &&
  69. (pParent->IsKindOf(RUNTIME_CLASS(CDomain)) ||
  70. pParent->IsKindOf(RUNTIME_CLASS(CMapping)) ||
  71. pParent->IsKindOf(RUNTIME_CLASS(CController))));
  72. #endif // ENABLE_PARENT_CHECK
  73. m_pParent = pParent;
  74. ASSERT(pName && *pName);
  75. if (pParent && pParent->IsKindOf(RUNTIME_CLASS(CDomain)))
  76. {
  77. m_strName = ((CDomain*)m_pParent)->m_strName;
  78. m_strName += _T("\\");
  79. m_strName += pName;
  80. }
  81. else
  82. m_strName = pName;
  83. m_strMapping = pMapping;
  84. m_bIsMapped = pMapping && *pMapping;
  85. m_lInUse = lInUse;
  86. m_lUnlicensed = lUnlicensed;
  87. m_bIsValid = ( 0 != ( dwFlags & LLS_FLAG_LICENSED ) );
  88. m_bIsBackOffice = ( 0 != ( dwFlags & LLS_FLAG_SUITE_USE ) );
  89. m_pStatistics = NULL;
  90. m_statisticArray.RemoveAll();
  91. m_bStatisticsRefreshed = FALSE;
  92. m_strProducts = pProducts;
  93. }
  94. CUser::~CUser()
  95. /*++
  96. Routine Description:
  97. Destructor for user object.
  98. Arguments:
  99. None.
  100. Return Values:
  101. None.
  102. --*/
  103. {
  104. if (m_pStatistics)
  105. m_pStatistics->InternalRelease();
  106. }
  107. void CUser::OnFinalRelease()
  108. /*++
  109. Routine Description:
  110. When the last reference for an automation object is released
  111. OnFinalRelease is called. This implementation deletes object.
  112. Arguments:
  113. None.
  114. Return Values:
  115. None.
  116. --*/
  117. {
  118. ResetStatistics();
  119. delete this;
  120. }
  121. LPDISPATCH CUser::GetApplication()
  122. /*++
  123. Routine Description:
  124. Returns the application object.
  125. Arguments:
  126. None.
  127. Return Values:
  128. VT_DISPATCH.
  129. --*/
  130. {
  131. return theApp.GetAppIDispatch();
  132. }
  133. long CUser::GetInUse()
  134. /*++
  135. Routine Description:
  136. Returns the number of licenses that the user is consuming.
  137. Arguments:
  138. None.
  139. Return Values:
  140. VT_I4.
  141. --*/
  142. {
  143. return m_lInUse;
  144. }
  145. BSTR CUser::GetFullName()
  146. /*++
  147. Routine Description:
  148. Returns fully qualified name of user.
  149. Arguments:
  150. None.
  151. Return Values:
  152. VT_BSTR.
  153. --*/
  154. {
  155. return GetName();
  156. }
  157. BSTR CUser::GetMapping()
  158. /*++
  159. Routine Description:
  160. Returns name of mapping user added to, if any.
  161. Arguments:
  162. None.
  163. Return Values:
  164. VT_BSTR.
  165. --*/
  166. {
  167. return m_strMapping.AllocSysString();
  168. }
  169. BSTR CUser::GetName()
  170. /*++
  171. Routine Description:
  172. Returns the name of the user.
  173. Arguments:
  174. None.
  175. Return Values:
  176. VT_BSTR.
  177. --*/
  178. {
  179. return m_strName.AllocSysString();
  180. }
  181. LPDISPATCH CUser::GetParent()
  182. /*++
  183. Routine Description:
  184. Returns the parent of the object.
  185. Arguments:
  186. None.
  187. Return Values:
  188. VT_DISPATCH.
  189. --*/
  190. {
  191. return m_pParent ? m_pParent->GetIDispatch(TRUE) : NULL;
  192. }
  193. LPDISPATCH CUser::GetStatistics(const VARIANT FAR& index)
  194. /*++
  195. Routine Description:
  196. Returns a collection object containing all of the
  197. usage statistics recorded on the license controller
  198. pertaining to the user or returns an individual
  199. usage statistic pertaining to the user described
  200. by an index into the collection.
  201. Arguments:
  202. index - optional argument that may be a number (VT_I4)
  203. indicating the position within collection.
  204. Return Values:
  205. VT_DISPATCH or VT_EMPTY.
  206. --*/
  207. {
  208. LPDISPATCH lpdispatch = NULL;
  209. if (!m_pStatistics)
  210. {
  211. m_pStatistics = new CStatistics(this, &m_statisticArray);
  212. }
  213. if (m_pStatistics)
  214. {
  215. if (V_ISVOID((VARIANT FAR*)&index))
  216. {
  217. if (RefreshStatistics())
  218. {
  219. lpdispatch = m_pStatistics->GetIDispatch(TRUE);
  220. }
  221. }
  222. else
  223. {
  224. if (m_bStatisticsRefreshed)
  225. {
  226. lpdispatch = m_pStatistics->GetItem(index);
  227. }
  228. else if (RefreshStatistics())
  229. {
  230. lpdispatch = m_pStatistics->GetItem(index);
  231. }
  232. }
  233. }
  234. else
  235. {
  236. LlsSetLastStatus(STATUS_NO_MEMORY);
  237. }
  238. return lpdispatch;
  239. }
  240. BOOL CUser::IsMapped()
  241. /*++
  242. Routine Description:
  243. Returns true if user is mapped.
  244. Arguments:
  245. None.
  246. Return Values:
  247. VT_BOOL.
  248. --*/
  249. {
  250. return m_bIsMapped;
  251. }
  252. BOOL CUser::Refresh()
  253. /*++
  254. Routine Description:
  255. Refreshs user object.
  256. Arguments:
  257. None.
  258. Return Values:
  259. VT_BOOL.
  260. --*/
  261. {
  262. NTSTATUS NtStatus;
  263. PLLS_USER_INFO_1 pUserInfo1 = NULL;
  264. NtStatus = ::LlsUserInfoGet(
  265. LlsGetActiveHandle(),
  266. MKSTR(m_strName),
  267. 1,
  268. (LPBYTE*)&pUserInfo1
  269. );
  270. if (NT_SUCCESS(NtStatus))
  271. {
  272. if (RefreshStatistics())
  273. {
  274. m_strMapping = pUserInfo1->Group;
  275. m_bIsMapped = pUserInfo1->Group && *pUserInfo1->Group;
  276. m_lInUse = pUserInfo1->Licensed;
  277. m_lUnlicensed = pUserInfo1->UnLicensed;
  278. m_bIsValid = ( 0 != ( pUserInfo1->Flags & LLS_FLAG_LICENSED ) );
  279. m_bIsBackOffice = ( 0 != ( pUserInfo1->Flags & LLS_FLAG_SUITE_USE ) );
  280. }
  281. else
  282. {
  283. NtStatus = LlsGetLastStatus();
  284. }
  285. #ifndef DISABLE_PER_NODE_ALLOCATION
  286. ::LlsFreeMemory(pUserInfo1->Name);
  287. ::LlsFreeMemory(pUserInfo1->Group);
  288. #endif // DISABLE_PER_NODE_ALLOCATION
  289. ::LlsFreeMemory(pUserInfo1);
  290. }
  291. LlsSetLastStatus(NtStatus); // called api
  292. return NT_SUCCESS(NtStatus);
  293. }
  294. BOOL CUser::RefreshStatistics()
  295. /*++
  296. Routine Description:
  297. Refreshs statistic object list.
  298. Arguments:
  299. None.
  300. Return Values:
  301. None.
  302. --*/
  303. {
  304. ResetStatistics();
  305. NTSTATUS NtStatus;
  306. DWORD ResumeHandle = 0L;
  307. int iStatistic = 0;
  308. do
  309. {
  310. DWORD EntriesRead;
  311. DWORD TotalEntries;
  312. LPBYTE ReturnBuffer = NULL;
  313. NtStatus = ::LlsUserProductEnum(
  314. LlsGetActiveHandle(),
  315. MKSTR(m_strName),
  316. 1,
  317. &ReturnBuffer,
  318. LLS_PREFERRED_LENGTH,
  319. &EntriesRead,
  320. &TotalEntries,
  321. &ResumeHandle
  322. );
  323. if (NtStatus == STATUS_SUCCESS ||
  324. NtStatus == STATUS_MORE_ENTRIES)
  325. {
  326. CStatistic* pStatistic;
  327. PLLS_USER_PRODUCT_INFO_1 pUserProductInfo1;
  328. pUserProductInfo1 = (PLLS_USER_PRODUCT_INFO_1)ReturnBuffer;
  329. ASSERT(iStatistic == m_statisticArray.GetSize());
  330. m_statisticArray.SetSize(m_statisticArray.GetSize() + EntriesRead);
  331. while (EntriesRead--)
  332. {
  333. pStatistic = new CStatistic(
  334. this,
  335. pUserProductInfo1->Product,
  336. pUserProductInfo1->Flags,
  337. pUserProductInfo1->LastUsed,
  338. pUserProductInfo1->UsageCount
  339. );
  340. m_statisticArray.SetAt(iStatistic++, pStatistic); // validate later...
  341. #ifndef DISABLE_PER_NODE_ALLOCATION
  342. ::LlsFreeMemory(pUserProductInfo1->Product);
  343. #endif // DISABLE_PER_NODE_ALLOCATION
  344. pUserProductInfo1++;
  345. }
  346. ::LlsFreeMemory(ReturnBuffer);
  347. }
  348. } while (NtStatus == STATUS_MORE_ENTRIES);
  349. LlsSetLastStatus(NtStatus); // called api
  350. if (NT_SUCCESS(NtStatus))
  351. {
  352. m_bStatisticsRefreshed = TRUE;
  353. }
  354. else
  355. {
  356. ResetStatistics();
  357. }
  358. return m_bStatisticsRefreshed;
  359. }
  360. void CUser::ResetStatistics()
  361. /*++
  362. Routine Description:
  363. Resets statistic object list.
  364. Arguments:
  365. None.
  366. Return Values:
  367. None.
  368. --*/
  369. {
  370. CStatistic* pStatistic;
  371. INT_PTR iStatistic = m_statisticArray.GetSize();
  372. while (iStatistic--)
  373. {
  374. if (pStatistic = (CStatistic*)m_statisticArray[iStatistic])
  375. {
  376. ASSERT(pStatistic->IsKindOf(RUNTIME_CLASS(CStatistic)));
  377. pStatistic->InternalRelease();
  378. }
  379. }
  380. m_statisticArray.RemoveAll();
  381. m_bStatisticsRefreshed = FALSE;
  382. }
  383. long CUser::GetUnlicensed()
  384. {
  385. return m_lUnlicensed;
  386. }