427 lines
11 KiB
C++
427 lines
11 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|
|
|