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.
 
 
 
 
 
 

426 lines
11 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: install.cxx
//
// Contents: Routines for queries/install of application state in the DS.
//
// Functions:
//
// History: Feb-97 DKays Created
// Nov-97 DebiM Changed for Beta2
//
//--------------------------------------------------------------------------
#include "cstore.hxx"
extern IClassAccess * gpClassAccess;
//HRESULT InstallAppDetail( DWORD dwActFlags, APPDETAIL *pAppDetail );
HRESULT DarwinPackageAssign( LPCWSTR pwszScript, BOOL InstallNow );
void GetDefaultPlatform(CSPLATFORM *pPlatform);
//+-------------------------------------------------------------------------
//
// CSGetClass
//
// Attempts to lookup and possibly install a class.
//
//--------------------------------------------------------------------------
HRESULT CSGetClass(
DWORD dwFlags,
uCLSSPEC * pClassSpec,
QUERYCONTEXT * pQueryContext,
CLSID * pClsid,
INSTALLINFO ** ppInstallInfo
)
{
HRESULT hr;
QUERYCONTEXT QueryContext;
INSTALLINFO InstallInfo;
*pClsid = CLSID_NULL;
*ppInstallInfo = 0;
if ( pQueryContext )
{
QueryContext = *pQueryContext;
}
else
{
QueryContext.dwContext = CLSCTX_ALL;
GetDefaultPlatform( &QueryContext.Platform );
QueryContext.Locale = GetThreadLocale();
QueryContext.dwVersionHi = (DWORD) -1;
QueryContext.dwVersionLo = (DWORD) -1;
}
if ( ! gpClassAccess )
return CS_E_NO_CLASSSTORE;
hr = gpClassAccess->GetAppInfo( pClassSpec, &QueryContext, &InstallInfo );
if ( hr != S_OK )
return hr;
//
// Only one package is returned.
//
#ifdef DARWIN_ENABLED
if ( DrwFilePath == InstallInfo.PathType )
{
hr = DarwinPackageAssign( InstallInfo.pszScriptPath, FALSE );
}
else
#endif
{
/*
* The APPDETAIL contains a bunch of useless info that we're not
* using. If you need this stuff, then you'll have to change
* the InstallAppDetail routine to work correctly with per-user
* registry.
*
if ( pPackageDetail->pAppDetail )
{
for ( DWORD i = 0; i < pPackageDetail->cApps; i++ )
{
hr = InstallAppDetail( pPackageDetail->dwActFlags,
&pPackageDetail->pAppDetail[i] );
if ( hr != S_OK )
{
FreePackageInfo( &Package );
return hr;
}
}
}
*/
//
// Return one of the ClassIDs. This is for IE use only.
//
if ( pClassSpec->tyspec != TYSPEC_CLSID )
{
if ( InstallInfo.pClsid )
*pClsid = *(InstallInfo.pClsid);
}
/* following is not necessary with the simplification for beta2 - DebiM
//
// This information is processed here and does not need to be sent
// to the client.
//
FreeAppDetail( pPackageDetail->pAppDetail );
MIDL_user_free( pPackageDetail->pAppDetail );
pPackageDetail->cApps = 0;
pPackageDetail->pAppDetail = 0;
if ( Package.cPackages > 1 )
{
*ppPackageDetail = (PACKAGEDETAIL *) MIDL_user_allocate( sizeof(PACKAGEDETAIL) );
if ( *ppPackageDetail )
{
**ppPackageDetail = *pPackageDetail;
Package.pPackageDetail[0] = Package.pPackageDetail[Package.cPackages - 1];
}
}
else
{
*ppPackageDetail = pPackageDetail;
Package.pPackageDetail = 0;
}
if ( *ppPackageDetail )
Package.cPackages--;
//End of Beta2 simplification
*/
}
*ppInstallInfo = (INSTALLINFO *) CoTaskMemAlloc (sizeof(INSTALLINFO));
memcpy( *ppInstallInfo, &InstallInfo, sizeof(INSTALLINFO) );
return hr;
}
/*
//+---------------------------------------------------------------------------
//
// Function: InstallAppDetail
//
// Synopsis: Installs an APPDETAIL obtained from the class store.
//
//----------------------------------------------------------------------------
HRESULT InstallAppDetail(
DWORD dwActFlags//,
//APPDETAIL *pAppDetail)
{
HRESULT hr = S_OK;
DWORD status;
WCHAR wszAppid[40];
DWORD dwOptions;
HKEY hkAppID;
HKEY hkCLSID;
DWORD Count;
DWORD Type;
DWORD Size;
DWORD Length;
DWORD Disp;
if(!pAppDetail)
return E_INVALIDARG;
if(pAppDetail->AppID == GUID_NULL)
return E_INVALIDARG;
(void) wStringFromGUID2(
pAppDetail->AppID,
wszAppid,
sizeof(wszAppid) );
if(dwActFlags & ACTFLG_RunOnce)
{
dwOptions = REG_OPTION_VOLATILE;
}
else
{
dwOptions = REG_OPTION_NON_VOLATILE;
}
//
//Register the APPID.
//
if(dwActFlags & ACTFLG_SystemWide)
{
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"Software\\Classes\\AppID",
0,
KEY_WRITE,
&hkAppID);
}
else
{
status = RegOpenKeyEx(HKEY_CLASSES_ROOT,
L"AppID",
0,
KEY_WRITE,
&hkAppID);
}
if(ERROR_SUCCESS == status)
{
HKEY hAppid;
status = RegCreateKeyEx(
hkAppID,
wszAppid,
0,
NULL,
dwOptions,
KEY_WRITE,
NULL,
&hAppid,
&Disp );
if(ERROR_SUCCESS == status)
{
WCHAR * pwszNames = 0;
HKEY hkSettings;
unsigned __int64 time;
SYSTEMTIME systemTime;
//
//Write the last refresh time.
//
GetLocalTime(&systemTime);
SystemTimeToFileTime(&systemTime, (FILETIME *)&time);
status = RegSetValueEx(hAppid,
L"LastRefresh",
0,
REG_BINARY,
(LPBYTE) &time,
sizeof(time));
//
//Write the remote server name.
//
Size = 0;
for ( Count = 0; Count < pAppDetail->cServers; Count++ )
Size += (lstrlenW(pAppDetail->prgServerNames[Count]) + 1) * sizeof(WCHAR);
if (pAppDetail->cServers == 1)
{
Type = REG_SZ;
pwszNames = pAppDetail->prgServerNames[0];
}
else if (pAppDetail->cServers > 1)
{
Size += sizeof(WCHAR);
pwszNames = (WCHAR *) alloca( Size );
if(pwszNames != 0)
{
pwszNames[0] = 0;
Length = 0;
for ( Count = 0; Count < pAppDetail->cServers; Count++ )
{
lstrcpyW( &pwszNames[Length], pAppDetail->prgServerNames[Count] );
Length += lstrlenW(pAppDetail->prgServerNames[Count]) + 1;
}
pwszNames[Length] = 0;
Type = REG_MULTI_SZ;
}
else
{
hr = E_OUTOFMEMORY;
}
}
if(pwszNames != NULL)
{
status = RegSetValueEx(hAppid,
L"RemoteServerName",
0,
Type,
(PBYTE) pwszNames,
Size );
if(STATUS_SUCCESS != status)
{
hr = HRESULT_FROM_WIN32(status);
}
}
RegCloseKey( hAppid );
}
else
{
hr = HRESULT_FROM_WIN32(status);
}
RegCloseKey(hkAppID);
}
else
{
hr = HRESULT_FROM_WIN32(status);
}
if(FAILED(hr))
{
return hr;
}
//
// Add the APPID value to all of the CLSIDs.
//
if(dwActFlags & ACTFLG_SystemWide)
{
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"Software\\Classes\\CLSID",
0,
KEY_WRITE,
&hkCLSID);
}
else
{
status = RegOpenKeyEx(HKEY_CLASSES_ROOT,
L"CLSID",
0,
KEY_WRITE,
&hkCLSID);
}
if(STATUS_SUCCESS == status)
{
HKEY hClsid;
WCHAR wszClsid[40];
for ( Count = 0; Count < pAppDetail->cClasses; Count++ )
{
(void) wStringFromGUID2(
pAppDetail->prgClsIdList[Count],
wszClsid,
sizeof(wszClsid) );
status = RegCreateKeyEx(hkCLSID,
wszClsid,
0,
NULL,
dwOptions,
KEY_SET_VALUE,
NULL,
&hClsid,
&Disp );
if (STATUS_SUCCESS == status)
{
status = RegSetValueEx(hClsid,
L"APPID",
0,
REG_SZ,
(PBYTE) wszAppid,
GUIDSTR_MAX * sizeof(WCHAR) );
if (status != STATUS_SUCCESS)
{
hr = HRESULT_FROM_WIN32(status);
}
RegCloseKey(hClsid);
}
else
{
hr = HRESULT_FROM_WIN32(status);
}
}
RegCloseKey(hkCLSID);
}
else
{
hr = HRESULT_FROM_WIN32(status);
}
return hr;
}
*/
#ifdef DARWIN_ENABLED
HRESULT
DarwinPackageAssign(
IN LPCWSTR pwszScript,
IN BOOL InstallNow )
{
BOOL bStatus;
HRESULT hr;
hr = RpcImpersonateClient( NULL );
if (hr != RPC_S_OK)
return hr;
bStatus = AssignApplication( pwszScript, InstallNow );
RevertToSelf();
if ( ! bStatus )
return HRESULT_FROM_WIN32( GetLastError() );
return S_OK;
}
#endif
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;
}