windows-nt/Source/XPSP1/NT/com/ole32/cs/cstore/csmain.cxx
2020-09-26 16:20:57 +08:00

594 lines
14 KiB
C++

//+------------------------------------------------------------------------
//
// 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;
}