//+------------------------------------------------------------------------ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1997 // // File: csmain.cxx // // Contents: Main cxx for Directory Class Access Implementation // Local Server. // // Author: DebiM // //------------------------------------------------------------------------- #include "cstore.hxx" // // Link list pointer for Class Containers Seen // CLASSCONTAINER *gpContainerHead = NULL; // // Link list pointer for User Profiles Seen // USERPROFILE *gpUserHead = NULL; // // Class Factory Objects // long ObjectCount = 0; CAppContainerCF * pCF = NULL; CClassAccessCF * pCSAccessCF = NULL; extern CClassContainerCF *g_pCF; //IClassAccess * gpClassAccess = NULL; // // Critical Section for Sid List // CRITICAL_SECTION ClassStoreBindList; // //--------------------------------------------------------------------- // Following are used for Supporting Test Scenarios thru FlushSidCache. WCHAR pwszDebugPath [_MAX_PATH]; BOOL fDebugPath = FALSE; //--------------------------------------------------------------------- // // ResetClassStoreState // -------------------- // // Synopsis: Calling this will close all Class Containers // in use and also cleanup state information about all user sids // that have initiated Class Store requests. // This routine is called at during shut down of // Class Store Server. // // Arguments: None // // Returns: None // void ResetClassStoreState() // // This routine is called at during shut down of Class Store Server // { // // Check if there are any outstanding open Class Stores // CLASSCONTAINER *pCS = gpContainerHead, *pCSTemp; while (pCS != NULL) { if (pCS->gpClassStore) { (pCS->gpClassStore)->Release(); pCS->gpClassStore = NULL; CSDbgPrint(("Found open container and closed.\n")); } if (pCS->pszClassStorePath) { CoTaskMemFree (pCS->pszClassStorePath); pCS->pszClassStorePath = NULL; } pCSTemp = pCS->pNextClassStore; CoTaskMemFree (pCS); pCS = pCSTemp; } gpContainerHead = NULL; USERPROFILE *pUser = gpUserHead, *pUserTemp; while (pUser != NULL) { if (pUser->pCachedSid) CoTaskMemFree (pUser->pCachedSid); if (pUser->pUserStoreList) CoTaskMemFree (pUser->pUserStoreList); pUser->cUserStoreCount = 0; pUserTemp = pUser->pNextUser; CoTaskMemFree (pUser); pUser = pUserTemp; } gpUserHead = NULL; CSDbgPrint(("ResetClassStoreState completed.\n")); } // // ResetUserState // -------------- // // Synopsis: Calling this will flush all state information // about all user sids that have initiated // Class Store requests. // // It is called by the special test entry point // FlushSidCache. // // Arguments: LPOLESTR pwszNewPath as the new Class Store path for All // // Returns: None // void ResetUserState(LPOLESTR pwszNewPath) // { USERPROFILE *pUser = gpUserHead, *pUserTemp; while (pUser != NULL) { if (pUser->pCachedSid) CoTaskMemFree (pUser->pCachedSid); pUser->cUserStoreCount = 0; pUserTemp = pUser->pNextUser; CoTaskMemFree (pUser); pUser = pUserTemp; } gpUserHead = NULL; wcscpy (&pwszDebugPath[0], pwszNewPath); fDebugPath = TRUE; CSDbgPrint(("ResetUserState completed.\n")); } // // Uninitialize // ------------- // // Synopsis: Class Store Server Uninitialization. // Disconnects from all Class Containers in use. // Flushes out all State information using ResetClassStoreState. // Unregisters Server registrations etc.. // // Arguments: None // // Returns: None // void Uninitialize() { // // Cleanup all open containers // //ResetClassStoreState(); // // release the Class Factory objects // if (pCF) pCF->Release(); if (pCSAccessCF) pCSAccessCF->Release(); if (g_pCF) g_pCF->Release(); // // get rid of the critical section // DeleteCriticalSection(&ClassStoreBindList); } // // FlushSidCache // ------------- // // Synopsis: Supported for Testing Only. Not exposed thru any header. // Calling this empties out Class Store Cache. // // Arguments: pwszNewPath // // Returns: S_OK // HRESULT FlushSidCache (LPOLESTR pwszNewPath) { EnterCriticalSection (&ClassStoreBindList); ResetUserState(pwszNewPath); LeaveCriticalSection (&ClassStoreBindList); return S_OK; } //+--------------------------------------------------------------------------- // // Function: InitializeClassStore // // History: 7-25-96 DebiM Created // // This entry point is called at DLL attach //---------------------------------------------------------------------------- BOOL InitializeClassStore(BOOL fInit) { HRESULT hr; BOOL bStatus; ObjectCount = 1; /* ACL * pAcl; DWORD AclSize; SECURITY_DESCRIPTOR * pSD; SID LocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID }; SID InteractiveSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, SECURITY_INTERACTIVE_RID }; // Started manually. Don't go away. AclSize = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + 2 * sizeof(SID); pSD = (SECURITY_DESCRIPTOR *) PrivMemAlloc( sizeof(SECURITY_DESCRIPTOR) + 2 * sizeof(SID) + AclSize ); if ( ! pSD ) return FALSE; bStatus = TRUE; pAcl = (ACL *) ( ((BYTE *)&pSD[1]) + 2 * sizeof(SID) ); if ( ! InitializeAcl( pAcl, AclSize, ACL_REVISION2 ) || ! AddAccessAllowedAce( pAcl, ACL_REVISION2, COM_RIGHTS_EXECUTE, &LocalSystemSid ) || ! AddAccessAllowedAce( pAcl, ACL_REVISION2, COM_RIGHTS_EXECUTE, &InteractiveSid ) ) bStatus = FALSE; if ( ! InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION ) || ! SetSecurityDescriptorDacl( pSD, TRUE, pAcl, FALSE ) || ! SetSecurityDescriptorGroup( pSD, &LocalSystemSid, FALSE ) || ! SetSecurityDescriptorOwner( pSD, &LocalSystemSid, FALSE ) ) bStatus = FALSE; if ( bStatus ) { hr = CoInitializeSecurity( pSD, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL ); } PrivMemFree( pSD ); if ( ! bStatus || (hr != S_OK) ) { CSDbgPrint(("Class Store: Couldn't initialize security\n")); } */ /* if (fInit) { hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (hr) CSDbgPrint(("RPCSS : CoInitialize returned 0x%x.\n", hr)); } */ pCF = new CAppContainerCF(); pCSAccessCF = new CClassAccessCF(); NTSTATUS status = RtlInitializeCriticalSection(&ClassStoreBindList); /* hr = pCSAccessCF->CreateInstance( NULL, IID_IClassAccess, (void **) &gpClassAccess ); if ( hr != S_OK ) { CSDbgPrint(("RPCSS : Counldn't create ClassAccess 0x%x\n", hr)); return FALSE; } */ g_pCF = new CClassContainerCF; if (!pCF || !pCSAccessCF || !g_pCF || !NT_SUCCESS(status)) { ASSERT(FALSE); goto fail; } return TRUE; fail: if (pCF) delete pCF; if (pCSAccessCF) delete pCSAccessCF; if (g_pCF) { delete g_pCF; g_pCF = NULL; } return FALSE; } /* // Globals HINSTANCE g_hInst = NULL; //+--------------------------------------------------------------- // // Function: DllGetClassObject // // Synopsis: Standard DLL entrypoint for locating class factories // //---------------------------------------------------------------- STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID FAR* ppv) { HRESULT hr; size_t i; if (IsEqualCLSID(clsid, CLSID_ClassAccess)) { return pCSAccessCF->QueryInterface(iid, ppv); } *ppv = NULL; return E_NOINTERFACE; } //+--------------------------------------------------------------- // // Function: DllCanUnloadNow // // Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded // //--------------------------------------------------------------- STDAPI DllCanUnloadNow(void) { HRESULT hr; hr = S_FALSE; // // BugBug // if (ulObjectCount > 0) hr = S_FALSE; else hr = S_OK; return hr; } //+--------------------------------------------------------------- // // Function: LibMain // // Synopsis: Standard DLL initialization entrypoint // //--------------------------------------------------------------- EXTERN_C BOOL _CRTAPI1 LibMain(HINSTANCE hInst, ULONG ulReason, LPVOID pvReserved) { HRESULT hr; DWORD cbSize = _MAX_PATH; WCHAR wszUserName [_MAX_PATH]; switch (ulReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInst); g_hInst = hInst; InitializeClassStore(); break; case DLL_PROCESS_DETACH: Uninitialize(); break; default: break; } return TRUE; } //+--------------------------------------------------------------------------- // // Function: DllMain // // Synopsis: entry point for NT // //---------------------------------------------------------------------------- BOOL DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { return LibMain((HINSTANCE)hDll, dwReason, lpReserved); } */ //+------------------------------------------------------------------------- // // Function: CsGetClassAccess // // Synopsis: Returns an instantiated interface to the Class Store // Co-ordinator object in Rpcss. // // Arguments: [ppIClassAccess] - where to put class access interface pointer // // Returns: S_OK - Got a Class Access Successfully // E_FAIL // //-------------------------------------------------------------------------- STDAPI CsGetClassAccess( IClassAccess ** ppIClassAccess) { HRESULT hr; *ppIClassAccess = NULL; hr = pCSAccessCF->CreateInstance( NULL, IID_IClassAccess, (void **)ppIClassAccess); return hr; } //+------------------------------------------------------------------- // // CsEnumApps (DebiM 11/7/97) // // Returns an enumerator for packages in the Class Store (s). // The enumerator works across all class stores in the calling users profile. // // // This is used by: // - Add/Remove programs to select Corporate Apps // - winlogon to obtain the list of assigned apps // // Arguments: // [in] // pszPackageName : Optional Wildcard string for PackageName // pLastUsn : Optional Time Stamp for new packages // pCategory : Optional CategoryId // dwAppFlags : Per APPINFO_xxx in objbase.h // [out] // ppIEnumPackage : Returned Interface Pointer // // Returns : // S_OK or E_NO_CLASSSTORE // //-------------------------------------------------------------------- STDAPI CsEnumApps( LPOLESTR pszPackageName, // Wildcard string for PackageName GUID *pCategory, // CategoryId ULONGLONG *pLastUsn, // Time Stamp for new packages DWORD dwAppFlags, // Per APPINFO_xxx in objbase.h IEnumPackage **ppIEnumPackage // Returned Interface Pointer ) { HRESULT hr; IClassAccess * pIClassAccess = NULL; *ppIEnumPackage = NULL; // // Get an IClassAccess // hr = CsGetClassAccess(&pIClassAccess); if (!SUCCEEDED(hr)) return hr; // // Get the enumerator // hr = pIClassAccess->EnumPackages ( pszPackageName, pCategory, pLastUsn, dwAppFlags, ppIEnumPackage ); pIClassAccess->Release(); return hr; } void GetDefaultPlatform(CSPLATFORM *pPlatform) { OSVERSIONINFO VersionInformation; VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&VersionInformation); pPlatform->dwPlatformId = VersionInformation.dwPlatformId; pPlatform->dwVersionHi = VersionInformation.dwMajorVersion; pPlatform->dwVersionLo = VersionInformation.dwMinorVersion; pPlatform->dwProcessorArch = DEFAULT_ARCHITECTURE; } //+------------------------------------------------------------------- // // CsGetAppInfo // // Looks up the given class specification in the DS. If an application for // this class specification is found, then the application details are returned. // // Arguments : // //-------------------------------------------------------------------- STDAPI CsGetAppInfo( uCLSSPEC * pClassSpec, // Class Spec (GUID/Ext/MIME) QUERYCONTEXT * pQueryContext, INSTALLINFO * pInstallInfo ) { HRESULT hr; QUERYCONTEXT QueryContext; IClassAccess * pIClassAccess = NULL; if ( pQueryContext ) { QueryContext = *pQueryContext; } else { QueryContext.dwContext = CLSCTX_ALL; GetDefaultPlatform( &QueryContext.Platform ); QueryContext.Locale = GetThreadLocale(); QueryContext.dwVersionHi = (DWORD) -1; QueryContext.dwVersionLo = (DWORD) -1; } // // Get an IClassAccess // hr = CsGetClassAccess(&pIClassAccess); if (!SUCCEEDED(hr)) return hr; hr = pIClassAccess->GetAppInfo(pClassSpec, &QueryContext, pInstallInfo ); pIClassAccess->Release(); return hr; }