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.

373 lines
8.3 KiB

  1. //*************************************************************
  2. //
  3. // profile.hxx
  4. //
  5. // Header file for Profile.cpp
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 2000
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #ifndef _PROFILE_HXX_
  13. #define _PROFILE_HXX_
  14. #include "iprofile.h"
  15. //
  16. // Number of buckets in the hash table.
  17. //
  18. #define NUM_OF_BUCKETS 23
  19. //
  20. // Flags used by WatchHiveRefCount.
  21. //
  22. #define WHRC_UNLOAD_HIVE 0x00000001
  23. #define WHRC_UNLOAD_CLASSESROOT 0x00000002
  24. #define WHRC_NOT_HIVE_OPEN_HANDLE 0x00000004
  25. //
  26. // .Default HKEY_USERS
  27. //
  28. const LPTSTR DEFAULT_HKU = TEXT(".DEFAULT");
  29. //
  30. // Entries which contain the user profile critical sections. These entries are
  31. // used by the synchronization manager.
  32. //
  33. class CSEntry
  34. {
  35. public:
  36. CSEntry()
  37. {
  38. pNext = NULL;
  39. pSid = NULL;
  40. dwRef = 0;
  41. szRPCEndPoint = NULL;
  42. cbCookie = 0;
  43. pbCookie = NULL;
  44. }
  45. ~CSEntry()
  46. {
  47. pNext = NULL;
  48. pSid = NULL;
  49. if (szRPCEndPoint)
  50. LocalFree(szRPCEndPoint);
  51. if (pbCookie)
  52. LocalFree(pbCookie);
  53. }
  54. friend class CSyncManager;
  55. BOOL Initialize(LPTSTR pSid);
  56. void Uninitialize();
  57. void EnterCS();
  58. void LeaveCS();
  59. BOOL NoMoreUser();
  60. void IncrementRefCount();
  61. LPTSTR GetRPCEndPoint(void) { return szRPCEndPoint; }
  62. void SetRPCEndPoint(LPTSTR lpRPCEndPoint);
  63. BYTE* GetCookie() { return pbCookie; }
  64. DWORD GetCookieLen() { return cbCookie; }
  65. void SetCookie(BYTE* pbCookieIn, DWORD cbCookieIn);
  66. private:
  67. class CSEntry* pNext;
  68. LPTSTR pSid;
  69. CRITICAL_SECTION csUser;
  70. LPTSTR szRPCEndPoint;
  71. DWORD dwRef;
  72. DWORD cbCookie;
  73. BYTE* pbCookie;
  74. };
  75. //
  76. // Hash table. Uses chained bucket.
  77. //
  78. class BUCKET
  79. {
  80. public:
  81. BUCKET(LPTSTR ptszStr, CSEntry* pEntryParam)
  82. {
  83. ptszString = ptszStr;
  84. pEntry = pEntryParam;
  85. pNext = NULL;
  86. }
  87. ~BUCKET()
  88. {
  89. ptszString = NULL;
  90. pEntry = NULL;
  91. pNext = NULL;
  92. }
  93. BUCKET* pNext;
  94. LPTSTR ptszString;
  95. CSEntry* pEntry;
  96. };
  97. typedef BUCKET* PBUCKET;
  98. class CHashTable
  99. {
  100. public:
  101. CHashTable() {}
  102. ~CHashTable() {}
  103. void Initialize();
  104. DWORD Hash(LPTSTR ptszString);
  105. BOOL IsInTable(LPTSTR ptszString, CSEntry** ppCSEntry = NULL);
  106. BOOL HashAdd(LPTSTR ptszString, CSEntry* pCSEntry = NULL);
  107. void HashDelete(LPTSTR ptszString);
  108. private:
  109. PBUCKET Table[NUM_OF_BUCKETS];
  110. };
  111. //
  112. // The synchronization manager. This class synchronizes LoadUserProfile/
  113. // UnloadUserProfile calls.
  114. //
  115. class CSyncManager
  116. {
  117. public:
  118. //
  119. // Constructor.
  120. //
  121. CSyncManager()
  122. {
  123. pCSList = NULL;
  124. }
  125. //
  126. // Initializes the table, the list, and the critical section.
  127. //
  128. BOOL Initialize();
  129. //
  130. // Sync functions. These functions are protected by a critical section
  131. // No two users can update their locks at the same time. This can be
  132. // optimized but optimization requires a lot more code. This is also the
  133. // only place where user's profile locks gets held and released.
  134. //
  135. BOOL EnterLock(LPTSTR pSid, LPTSTR lpRPCEndPoint, BYTE* pbCookie, DWORD cbCookie);
  136. BOOL LeaveLock(LPTSTR pSid);
  137. HRESULT GetRPCEndPointAndCookie(LPTSTR pSid, LPTSTR* lplpEndPoint, BYTE** ppbCookie, DWORD* pcbCookie);
  138. private:
  139. CHashTable cTable; // All the user profile critical section's associated sids.
  140. CSEntry* pCSList;
  141. CRITICAL_SECTION cs;
  142. };
  143. //
  144. // Mapping between profile work lists and threads. This is for the registry
  145. // key leak fix.
  146. //
  147. class MAP
  148. {
  149. public:
  150. MAP();
  151. ~MAP() {}
  152. friend class CUserProfile;
  153. //
  154. // Delete/insert a work item from/into the map.
  155. //
  156. void Delete(DWORD dwIndex);
  157. void Insert(HANDLE hEvent, LPTSTR ptszSid);
  158. BOOL IsEmpty() { return dwItems <= 1; }
  159. LPTSTR GetSid(DWORD dwIndex);
  160. private:
  161. MAP* pNext;
  162. //
  163. // These two arrays must always be in sync.
  164. //
  165. HANDLE rghEvents[MAXIMUM_WAIT_OBJECTS];
  166. LPTSTR rgSids[MAXIMUM_WAIT_OBJECTS];
  167. DWORD dwItems;
  168. };
  169. typedef MAP* PMAP;
  170. //
  171. // The IUserProfile interface functions use this class api to do the core processing. User profiles are loaded
  172. // unloaded through the api provided in this class. Console winlogon is the server and only one global instance
  173. // of this class runs in console winlogon.
  174. //
  175. class CUserProfile
  176. {
  177. public:
  178. //
  179. // Constructor/Destructor.
  180. //
  181. CUserProfile() {bInitialized = FALSE; bConsoleWinlogon = FALSE; }
  182. ~CUserProfile() {};
  183. //
  184. // Initialization function.
  185. //
  186. void Initialize();
  187. //
  188. // Are we in console winlogon process?
  189. //
  190. BOOL IsConsoleWinlogon() { return bConsoleWinlogon; }
  191. //
  192. // Main function for the worker threads.
  193. //
  194. DWORD WorkerThreadMain(PMAP pmap);
  195. //
  196. // Make getting the user profile lock easier.
  197. //
  198. BOOL EnterUserProfileLockLocal(LPTSTR pSid);
  199. BOOL LeaveUserProfileLockLocal(LPTSTR pSid);
  200. //
  201. // The actual LoadUserProfile/UnloadUserProfile that does all the work.
  202. //
  203. BOOL LoadUserProfileP(HANDLE hTokenClient, HANDLE hTokenUser, LPPROFILEINFO lpProfileInfo, LPTSTR lpRPCEndPoint, BYTE* pbCookie, DWORD cbCookie);
  204. BOOL UnloadUserProfileP(HANDLE hTokenClient, HANDLE hTokenUser, HKEY hProfile, LPTSTR lpRPCEndPoint, BYTE* pbCookie, DWORD cbCookie);
  205. //
  206. // Get RPCEndPoint and security cookie associated with registered IProfileDialog interface
  207. //
  208. HRESULT GetRPCEndPointAndCookie(LPTSTR pSid, LPTSTR* lplpEndPoint, BYTE** ppbCookie, DWORD* pcbCookie);
  209. private:
  210. //
  211. // Handles the situation when keys are leaked from the registry.
  212. //
  213. DWORD HandleRegKeyLeak(LPTSTR lpSidString,
  214. LPPROFILE lpProfile,
  215. BOOL bUnloadHiveSucceeded,
  216. DWORD* dwWatchHiveFlags,
  217. DWORD* dwCopyTmpHive,
  218. LPTSTR pTmpHiveFile,
  219. DWORD cchTmpHiveFile);
  220. //
  221. // This function is called when a registry key is leaked.
  222. //
  223. STDMETHODIMP WatchHiveRefCount(LPCTSTR pctszSid, DWORD dwWHRCFlags);
  224. //
  225. // Get the reference count.
  226. //
  227. long GetRefCountAndFlags(LPCTSTR ptszSid, HKEY* phkPL, DWORD* dwRefCount, DWORD* dwInternalFlags);
  228. //
  229. // Add a new work item to both the map structure and a worker thread.
  230. //
  231. HRESULT AddWorkItem(LPCTSTR ptszSid, HANDLE hEvent);
  232. //
  233. // Get the exisiting work item event from map structure
  234. //
  235. HANDLE GetWorkItem(LPCTSTR ptszSid);
  236. //
  237. // Delete the profile as well if necessary, i.e.,
  238. // temporary profiles, guest profiles, and mandatory profiles.
  239. //
  240. void CleanupUserProfile(LPTSTR ptszSid, HKEY* phkProfileList);
  241. //
  242. // Reg leak fix structures. This hash table holds the sids of all the
  243. // unloaded user registry hives.
  244. //
  245. CRITICAL_SECTION csMap;
  246. PMAP pMap;
  247. CHashTable cTable;
  248. //
  249. // LoadUserProfile/UnloadUserProfile synchronization manager.
  250. //
  251. CSyncManager cSyncMgr;
  252. //
  253. // Tells the caller if we are already initialized. Also tells us if we are
  254. // in the console winlogon process because it's the only process that'll
  255. // initialize this object.
  256. //
  257. BOOL bInitialized;
  258. //
  259. // Tells us if we are in console winlogon process
  260. //
  261. BOOL bConsoleWinlogon;
  262. };
  263. //
  264. // Functions prototype for binding rpc handle
  265. //
  266. BOOL GetInterface(handle_t *phIfHandle, LPTSTR lpRPCEndPoint);
  267. BOOL ReleaseInterface(handle_t *phIfHandle);
  268. #endif