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.

593 lines
14 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: csmain.cxx
  7. //
  8. // Contents: Main cxx for Directory Class Access Implementation
  9. // Local Server.
  10. //
  11. // Author: DebiM
  12. //
  13. //-------------------------------------------------------------------------
  14. #include "cstore.hxx"
  15. //
  16. // Link list pointer for Class Containers Seen
  17. //
  18. CLASSCONTAINER *gpContainerHead = NULL;
  19. //
  20. // Link list pointer for User Profiles Seen
  21. //
  22. USERPROFILE *gpUserHead = NULL;
  23. //
  24. // Class Factory Objects
  25. //
  26. long ObjectCount = 0;
  27. CAppContainerCF * pCF = NULL;
  28. CClassAccessCF * pCSAccessCF = NULL;
  29. extern CClassContainerCF *g_pCF;
  30. //IClassAccess * gpClassAccess = NULL;
  31. //
  32. // Critical Section for Sid List
  33. //
  34. CRITICAL_SECTION ClassStoreBindList;
  35. //
  36. //---------------------------------------------------------------------
  37. // Following are used for Supporting Test Scenarios thru FlushSidCache.
  38. WCHAR pwszDebugPath [_MAX_PATH];
  39. BOOL fDebugPath = FALSE;
  40. //---------------------------------------------------------------------
  41. //
  42. // ResetClassStoreState
  43. // --------------------
  44. //
  45. // Synopsis: Calling this will close all Class Containers
  46. // in use and also cleanup state information about all user sids
  47. // that have initiated Class Store requests.
  48. // This routine is called at during shut down of
  49. // Class Store Server.
  50. //
  51. // Arguments: None
  52. //
  53. // Returns: None
  54. //
  55. void ResetClassStoreState()
  56. //
  57. // This routine is called at during shut down of Class Store Server
  58. //
  59. {
  60. //
  61. // Check if there are any outstanding open Class Stores
  62. //
  63. CLASSCONTAINER *pCS = gpContainerHead, *pCSTemp;
  64. while (pCS != NULL)
  65. {
  66. if (pCS->gpClassStore)
  67. {
  68. (pCS->gpClassStore)->Release();
  69. pCS->gpClassStore = NULL;
  70. CSDbgPrint(("Found open container and closed.\n"));
  71. }
  72. if (pCS->pszClassStorePath)
  73. {
  74. CoTaskMemFree (pCS->pszClassStorePath);
  75. pCS->pszClassStorePath = NULL;
  76. }
  77. pCSTemp = pCS->pNextClassStore;
  78. CoTaskMemFree (pCS);
  79. pCS = pCSTemp;
  80. }
  81. gpContainerHead = NULL;
  82. USERPROFILE *pUser = gpUserHead, *pUserTemp;
  83. while (pUser != NULL)
  84. {
  85. if (pUser->pCachedSid)
  86. CoTaskMemFree (pUser->pCachedSid);
  87. if (pUser->pUserStoreList)
  88. CoTaskMemFree (pUser->pUserStoreList);
  89. pUser->cUserStoreCount = 0;
  90. pUserTemp = pUser->pNextUser;
  91. CoTaskMemFree (pUser);
  92. pUser = pUserTemp;
  93. }
  94. gpUserHead = NULL;
  95. CSDbgPrint(("ResetClassStoreState completed.\n"));
  96. }
  97. //
  98. // ResetUserState
  99. // --------------
  100. //
  101. // Synopsis: Calling this will flush all state information
  102. // about all user sids that have initiated
  103. // Class Store requests.
  104. //
  105. // It is called by the special test entry point
  106. // FlushSidCache.
  107. //
  108. // Arguments: LPOLESTR pwszNewPath as the new Class Store path for All
  109. //
  110. // Returns: None
  111. //
  112. void ResetUserState(LPOLESTR pwszNewPath)
  113. //
  114. {
  115. USERPROFILE *pUser = gpUserHead, *pUserTemp;
  116. while (pUser != NULL)
  117. {
  118. if (pUser->pCachedSid)
  119. CoTaskMemFree (pUser->pCachedSid);
  120. pUser->cUserStoreCount = 0;
  121. pUserTemp = pUser->pNextUser;
  122. CoTaskMemFree (pUser);
  123. pUser = pUserTemp;
  124. }
  125. gpUserHead = NULL;
  126. wcscpy (&pwszDebugPath[0], pwszNewPath);
  127. fDebugPath = TRUE;
  128. CSDbgPrint(("ResetUserState completed.\n"));
  129. }
  130. //
  131. // Uninitialize
  132. // -------------
  133. //
  134. // Synopsis: Class Store Server Uninitialization.
  135. // Disconnects from all Class Containers in use.
  136. // Flushes out all State information using ResetClassStoreState.
  137. // Unregisters Server registrations etc..
  138. //
  139. // Arguments: None
  140. //
  141. // Returns: None
  142. //
  143. void Uninitialize()
  144. {
  145. //
  146. // Cleanup all open containers
  147. //
  148. //ResetClassStoreState();
  149. //
  150. // release the Class Factory objects
  151. //
  152. if (pCF)
  153. pCF->Release();
  154. if (pCSAccessCF)
  155. pCSAccessCF->Release();
  156. if (g_pCF)
  157. g_pCF->Release();
  158. //
  159. // get rid of the critical section
  160. //
  161. DeleteCriticalSection(&ClassStoreBindList);
  162. }
  163. //
  164. // FlushSidCache
  165. // -------------
  166. //
  167. // Synopsis: Supported for Testing Only. Not exposed thru any header.
  168. // Calling this empties out Class Store Cache.
  169. //
  170. // Arguments: pwszNewPath
  171. //
  172. // Returns: S_OK
  173. //
  174. HRESULT FlushSidCache (LPOLESTR pwszNewPath)
  175. {
  176. EnterCriticalSection (&ClassStoreBindList);
  177. ResetUserState(pwszNewPath);
  178. LeaveCriticalSection (&ClassStoreBindList);
  179. return S_OK;
  180. }
  181. //+---------------------------------------------------------------------------
  182. //
  183. // Function: InitializeClassStore
  184. //
  185. // History: 7-25-96 DebiM Created
  186. //
  187. // This entry point is called at DLL attach
  188. //----------------------------------------------------------------------------
  189. BOOL InitializeClassStore(BOOL fInit)
  190. {
  191. HRESULT hr;
  192. BOOL bStatus;
  193. ObjectCount = 1;
  194. /*
  195. ACL * pAcl;
  196. DWORD AclSize;
  197. SECURITY_DESCRIPTOR * pSD;
  198. SID LocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID };
  199. SID InteractiveSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, SECURITY_INTERACTIVE_RID };
  200. // Started manually. Don't go away.
  201. AclSize = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + 2 * sizeof(SID);
  202. pSD = (SECURITY_DESCRIPTOR *)
  203. PrivMemAlloc( sizeof(SECURITY_DESCRIPTOR) + 2 * sizeof(SID) + AclSize );
  204. if ( ! pSD )
  205. return FALSE;
  206. bStatus = TRUE;
  207. pAcl = (ACL *) ( ((BYTE *)&pSD[1]) + 2 * sizeof(SID) );
  208. if ( ! InitializeAcl( pAcl, AclSize, ACL_REVISION2 ) ||
  209. ! AddAccessAllowedAce( pAcl, ACL_REVISION2, COM_RIGHTS_EXECUTE, &LocalSystemSid ) ||
  210. ! AddAccessAllowedAce( pAcl, ACL_REVISION2, COM_RIGHTS_EXECUTE, &InteractiveSid ) )
  211. bStatus = FALSE;
  212. if ( ! InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION ) ||
  213. ! SetSecurityDescriptorDacl( pSD, TRUE, pAcl, FALSE ) ||
  214. ! SetSecurityDescriptorGroup( pSD, &LocalSystemSid, FALSE ) ||
  215. ! SetSecurityDescriptorOwner( pSD, &LocalSystemSid, FALSE ) )
  216. bStatus = FALSE;
  217. if ( bStatus )
  218. {
  219. hr = CoInitializeSecurity(
  220. pSD,
  221. -1,
  222. NULL,
  223. NULL,
  224. RPC_C_AUTHN_LEVEL_CONNECT,
  225. RPC_C_IMP_LEVEL_IDENTIFY,
  226. NULL,
  227. EOAC_NONE,
  228. NULL );
  229. }
  230. PrivMemFree( pSD );
  231. if ( ! bStatus || (hr != S_OK) )
  232. {
  233. CSDbgPrint(("Class Store: Couldn't initialize security\n"));
  234. }
  235. */
  236. /*
  237. if (fInit)
  238. {
  239. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  240. if (hr)
  241. CSDbgPrint(("RPCSS : CoInitialize returned 0x%x.\n", hr));
  242. }
  243. */
  244. pCF = new CAppContainerCF();
  245. pCSAccessCF = new CClassAccessCF();
  246. NTSTATUS status = RtlInitializeCriticalSection(&ClassStoreBindList);
  247. /* hr = pCSAccessCF->CreateInstance( NULL, IID_IClassAccess, (void **) &gpClassAccess );
  248. if ( hr != S_OK )
  249. {
  250. CSDbgPrint(("RPCSS : Counldn't create ClassAccess 0x%x\n", hr));
  251. return FALSE;
  252. }
  253. */
  254. g_pCF = new CClassContainerCF;
  255. if (!pCF || !pCSAccessCF || !g_pCF || !NT_SUCCESS(status))
  256. {
  257. ASSERT(FALSE);
  258. goto fail;
  259. }
  260. return TRUE;
  261. fail:
  262. if (pCF)
  263. delete pCF;
  264. if (pCSAccessCF)
  265. delete pCSAccessCF;
  266. if (g_pCF)
  267. {
  268. delete g_pCF;
  269. g_pCF = NULL;
  270. }
  271. return FALSE;
  272. }
  273. /*
  274. // Globals
  275. HINSTANCE g_hInst = NULL;
  276. //+---------------------------------------------------------------
  277. //
  278. // Function: DllGetClassObject
  279. //
  280. // Synopsis: Standard DLL entrypoint for locating class factories
  281. //
  282. //----------------------------------------------------------------
  283. STDAPI
  284. DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID FAR* ppv)
  285. {
  286. HRESULT hr;
  287. size_t i;
  288. if (IsEqualCLSID(clsid, CLSID_ClassAccess))
  289. {
  290. return pCSAccessCF->QueryInterface(iid, ppv);
  291. }
  292. *ppv = NULL;
  293. return E_NOINTERFACE;
  294. }
  295. //+---------------------------------------------------------------
  296. //
  297. // Function: DllCanUnloadNow
  298. //
  299. // Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded
  300. //
  301. //---------------------------------------------------------------
  302. STDAPI
  303. DllCanUnloadNow(void)
  304. {
  305. HRESULT hr;
  306. hr = S_FALSE;
  307. //
  308. // BugBug
  309. //
  310. if (ulObjectCount > 0)
  311. hr = S_FALSE;
  312. else
  313. hr = S_OK;
  314. return hr;
  315. }
  316. //+---------------------------------------------------------------
  317. //
  318. // Function: LibMain
  319. //
  320. // Synopsis: Standard DLL initialization entrypoint
  321. //
  322. //---------------------------------------------------------------
  323. EXTERN_C BOOL _CRTAPI1
  324. LibMain(HINSTANCE hInst, ULONG ulReason, LPVOID pvReserved)
  325. {
  326. HRESULT hr;
  327. DWORD cbSize = _MAX_PATH;
  328. WCHAR wszUserName [_MAX_PATH];
  329. switch (ulReason)
  330. {
  331. case DLL_PROCESS_ATTACH:
  332. DisableThreadLibraryCalls(hInst);
  333. g_hInst = hInst;
  334. InitializeClassStore();
  335. break;
  336. case DLL_PROCESS_DETACH:
  337. Uninitialize();
  338. break;
  339. default:
  340. break;
  341. }
  342. return TRUE;
  343. }
  344. //+---------------------------------------------------------------------------
  345. //
  346. // Function: DllMain
  347. //
  348. // Synopsis: entry point for NT
  349. //
  350. //----------------------------------------------------------------------------
  351. BOOL
  352. DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  353. {
  354. return LibMain((HINSTANCE)hDll, dwReason, lpReserved);
  355. }
  356. */
  357. //+-------------------------------------------------------------------------
  358. //
  359. // Function: CsGetClassAccess
  360. //
  361. // Synopsis: Returns an instantiated interface to the Class Store
  362. // Co-ordinator object in Rpcss.
  363. //
  364. // Arguments: [ppIClassAccess] - where to put class access interface pointer
  365. //
  366. // Returns: S_OK - Got a Class Access Successfully
  367. // E_FAIL
  368. //
  369. //--------------------------------------------------------------------------
  370. STDAPI CsGetClassAccess(
  371. IClassAccess ** ppIClassAccess)
  372. {
  373. HRESULT hr;
  374. *ppIClassAccess = NULL;
  375. hr = pCSAccessCF->CreateInstance( NULL,
  376. IID_IClassAccess,
  377. (void **)ppIClassAccess);
  378. return hr;
  379. }
  380. //+-------------------------------------------------------------------
  381. //
  382. // CsEnumApps (DebiM 11/7/97)
  383. //
  384. // Returns an enumerator for packages in the Class Store (s).
  385. // The enumerator works across all class stores in the calling users profile.
  386. //
  387. //
  388. // This is used by:
  389. // - Add/Remove programs to select Corporate Apps
  390. // - winlogon to obtain the list of assigned apps
  391. //
  392. // Arguments:
  393. // [in]
  394. // pszPackageName : Optional Wildcard string for PackageName
  395. // pLastUsn : Optional Time Stamp for new packages
  396. // pCategory : Optional CategoryId
  397. // dwAppFlags : Per APPINFO_xxx in objbase.h
  398. // [out]
  399. // ppIEnumPackage : Returned Interface Pointer
  400. //
  401. // Returns :
  402. // S_OK or E_NO_CLASSSTORE
  403. //
  404. //--------------------------------------------------------------------
  405. STDAPI
  406. CsEnumApps(
  407. LPOLESTR pszPackageName, // Wildcard string for PackageName
  408. GUID *pCategory, // CategoryId
  409. ULONGLONG *pLastUsn, // Time Stamp for new packages
  410. DWORD dwAppFlags, // Per APPINFO_xxx in objbase.h
  411. IEnumPackage **ppIEnumPackage // Returned Interface Pointer
  412. )
  413. {
  414. HRESULT hr;
  415. IClassAccess * pIClassAccess = NULL;
  416. *ppIEnumPackage = NULL;
  417. //
  418. // Get an IClassAccess
  419. //
  420. hr = CsGetClassAccess(&pIClassAccess);
  421. if (!SUCCEEDED(hr))
  422. return hr;
  423. //
  424. // Get the enumerator
  425. //
  426. hr = pIClassAccess->EnumPackages (
  427. pszPackageName,
  428. pCategory,
  429. pLastUsn,
  430. dwAppFlags,
  431. ppIEnumPackage
  432. );
  433. pIClassAccess->Release();
  434. return hr;
  435. }
  436. void
  437. GetDefaultPlatform(CSPLATFORM *pPlatform)
  438. {
  439. OSVERSIONINFO VersionInformation;
  440. VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  441. GetVersionEx(&VersionInformation);
  442. pPlatform->dwPlatformId = VersionInformation.dwPlatformId;
  443. pPlatform->dwVersionHi = VersionInformation.dwMajorVersion;
  444. pPlatform->dwVersionLo = VersionInformation.dwMinorVersion;
  445. pPlatform->dwProcessorArch = DEFAULT_ARCHITECTURE;
  446. }
  447. //+-------------------------------------------------------------------
  448. //
  449. // CsGetAppInfo
  450. //
  451. // Looks up the given class specification in the DS. If an application for
  452. // this class specification is found, then the application details are returned.
  453. //
  454. // Arguments :
  455. //
  456. //--------------------------------------------------------------------
  457. STDAPI
  458. CsGetAppInfo(
  459. uCLSSPEC * pClassSpec, // Class Spec (GUID/Ext/MIME)
  460. QUERYCONTEXT * pQueryContext,
  461. INSTALLINFO * pInstallInfo
  462. )
  463. {
  464. HRESULT hr;
  465. QUERYCONTEXT QueryContext;
  466. IClassAccess * pIClassAccess = NULL;
  467. if ( pQueryContext )
  468. {
  469. QueryContext = *pQueryContext;
  470. }
  471. else
  472. {
  473. QueryContext.dwContext = CLSCTX_ALL;
  474. GetDefaultPlatform( &QueryContext.Platform );
  475. QueryContext.Locale = GetThreadLocale();
  476. QueryContext.dwVersionHi = (DWORD) -1;
  477. QueryContext.dwVersionLo = (DWORD) -1;
  478. }
  479. //
  480. // Get an IClassAccess
  481. //
  482. hr = CsGetClassAccess(&pIClassAccess);
  483. if (!SUCCEEDED(hr))
  484. return hr;
  485. hr = pIClassAccess->GetAppInfo(pClassSpec, &QueryContext, pInstallInfo );
  486. pIClassAccess->Release();
  487. return hr;
  488. }