Leaked source code of windows server 2003
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.
 
 
 
 
 
 

511 lines
15 KiB

/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
setup.cpp
Abstract:
This file contains the code responsible for the install/uninstall of the
Help system.
Revision History:
Davide Massarenti (Dmassare) 04/19/2000
created
******************************************************************************/
#include "stdafx.h"
#include <unattend.h>
#include <aclapi.h>
#include <initguid.h>
#include <mstask.h> // for task scheduler apis
#include <msterr.h>
////////////////////////////////////////////////////////////////////////////////
static const WCHAR c_szMessageFile [] = HC_ROOT_HELPSVC_BINARIES L"\\HCAppRes.dll";
#define REG_CONTROL L"System\\CurrentControlSet\\Control"
#define REG_TSERVER L"Terminal Server"
#define REG_CONTROL_TSERVER REG_CONTROL L"\\" REG_TSERVER
#define REG_CONTROL_GETHELP REG_CONTROL_TSERVER
#define POLICY_TS_REMDSK_ALLOWTOGETHELP L"fAllowToGetHelp"
static const WCHAR c_szRegistryLog [] = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\HelpSvc";
static const WCHAR c_szRegistryLog_File [] = L"EventMessageFile";
static const WCHAR c_szRegistryLog_Flags[] = L"TypesSupported";
static const DWORD SETUP_LOCALIZATION_STRINGS = 0x00000001;
static const DWORD SETUP_MESSAGE_FILE = 0x00000002;
static const DWORD SETUP_CREATE_GROUP = 0x00000004;
static const DWORD SETUP_OEMINFO = 0x00000008;
static const DWORD SETUP_SKU_INSTALL = 0x00000010;
static const MPC::StringToBitField c_Setup[] =
{
{ L"LOCALIZATION_STRINGS", SETUP_LOCALIZATION_STRINGS, SETUP_LOCALIZATION_STRINGS, -1 },
{ L"MESSAGE_FILE" , SETUP_MESSAGE_FILE , SETUP_MESSAGE_FILE , -1 },
{ L"CREATE_GROUP" , SETUP_CREATE_GROUP , SETUP_CREATE_GROUP , -1 },
{ L"OEMINFO" , SETUP_OEMINFO , SETUP_OEMINFO , -1 },
{ L"SKU_INSTALL" , SETUP_SKU_INSTALL , SETUP_SKU_INSTALL , -1 },
{ NULL }
};
////////////////////////////////////////////////////////////////////////////////
static HRESULT DumpSD( /*[in]*/ LPCWSTR szFile ,
/*[in]*/ CPCHSecurityDescriptorDirect& sdd )
{
__MPC_FUNC_ENTRY( COMMONID, "DumpSD" );
HRESULT hr;
CComPtr<CPCHSecurityDescriptor> pNew;
CComPtr<IStream> pStreamIn;
CComPtr<IStream> pStreamOut;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pNew ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertSDToCOM( pNew ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pNew->SaveXMLAsStream ( (IUnknown**)&pStreamIn ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::OpenStreamForWrite( szFile, &pStreamOut ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( pStreamIn, pStreamOut ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
static void local_RemoveRegistryBackup()
{
MPC::RegKey rkBase;
if(SUCCEEDED(rkBase.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rkBase.Attach ( HC_REGISTRY_HELPSVC L"\\Backup" )) )
{
(void)rkBase.Delete( /*fDeep*/true );
}
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Local_Install()
{
__HCP_FUNC_ENTRY( "Local_Install" );
HRESULT hr;
MPC::wstring strGroupName;
MPC::wstring strGroupComment;
DWORD dwStatus = SETUP_LOCALIZATION_STRINGS |
SETUP_MESSAGE_FILE |
SETUP_CREATE_GROUP |
SETUP_OEMINFO |
SETUP_SKU_INSTALL;
if(SUCCEEDED(MPC::LocalizeString( IDS_HELPSVC_GROUPNAME , strGroupName )) &&
SUCCEEDED(MPC::LocalizeString( IDS_HELPSVC_GROUPCOMMENT, strGroupComment )) )
{
dwStatus &= ~SETUP_LOCALIZATION_STRINGS;
}
////////////////////////////////////////////////////////////////////////////////
//
// Register the message file into the registry.
//
{
MPC::wstring strPath ( c_szMessageFile ); MPC::SubstituteEnvVariables( strPath );
MPC::RegKey rkEventLog;
CComVariant vValue;
if(SUCCEEDED(rkEventLog.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rkEventLog.Attach ( c_szRegistryLog )) &&
SUCCEEDED(rkEventLog.Create ( )) )
{
if(SUCCEEDED(rkEventLog.put_Value( (vValue = strPath.c_str()), c_szRegistryLog_File )) &&
SUCCEEDED(rkEventLog.put_Value( (vValue = (long)0x1F ), c_szRegistryLog_Flags )) )
{
dwStatus &= ~SETUP_MESSAGE_FILE;
}
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Remove old WinME directory and registry keys.
//
{
MPC::RegKey rkRun;
(void)SVC::RemoveAndRecreateDirectory( HC_ROOT L"\\Support", NULL, /*fRemove*/true, /*fRecreate*/false );
if(SUCCEEDED(rkRun.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rkRun.Attach ( L"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\PCHealth" )) )
{
(void)rkRun.Delete( true );
}
}
//
// Remove old task scheduler entry.
//
{
CComBSTR bstrTaskName;
if(SUCCEEDED(MPC::LocalizeString( IDS_HELPSVC_TASKNAME, bstrTaskName )))
{
CComPtr<ITaskScheduler> pTaskScheduler;
if(SUCCEEDED(::CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void**)&pTaskScheduler )))
{
(void)pTaskScheduler->Delete( bstrTaskName );
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Before PCHealthUnAttendedSetup() happens, we need to set the default
// reg key for fAllowToGetHelp (0 for Server and 1 for Per/Pro)
{
BOOL bPerPro = FALSE;
DWORDLONG dwlConditionMask;
OSVERSIONINFOEX osVersionInfo;
RtlZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.wProductType = VER_NT_WORKSTATION;
dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_PRODUCT_TYPE, VER_EQUAL);
// Is this machine Personal or Pro? Opposed to Server.
bPerPro = VerifyVersionInfo(
&osVersionInfo,
VER_PRODUCT_TYPE,
dwlConditionMask
);
DWORD dwValue;
DWORD dwStatus;
DWORD dwSize;
DWORD dwType;
HKEY hKey;
//
// Open TS registry key under HKLM\System\CurrentControlSet\Control\Terminal Serv...
//
dwStatus = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
REG_CONTROL_GETHELP,
0,
KEY_READ | KEY_WRITE,
&hKey
);
if( ERROR_SUCCESS == dwStatus )
{
dwSize = sizeof(dwValue);
dwStatus = RegQueryValueEx(
hKey,
POLICY_TS_REMDSK_ALLOWTOGETHELP,
0,
&dwType,
(PBYTE)&dwValue,
&dwSize
);
if( ERROR_FILE_NOT_FOUND == dwStatus || REG_DWORD != dwType )
{
//
// default is not allow to get help if
// value does not exist.
//
if( bPerPro )
{
dwValue = 1;
}
else
{
dwValue = 0;
}
dwStatus = RegSetValueEx(
hKey,
POLICY_TS_REMDSK_ALLOWTOGETHELP,
0,
REG_DWORD,
(PBYTE)&dwValue,
sizeof(dwValue)
);
}
RegCloseKey( hKey );
}
}
////////////////////////////////////////////////////////////////////////////////
try
{
::PCHealthUnAttendedSetup();
}
catch(...)
{
}
////////////////////////////////////////////////////////////////////////////////
//
// Create our group: "HelpServicesGroup".
//
{
CPCHAccounts acc;
if(SUCCEEDED(acc.CreateGroup( strGroupName.c_str(), strGroupComment.c_str() )))
{
dwStatus &= ~SETUP_CREATE_GROUP;
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Extract OEM info from oeminfo.ini
//
{
MPC::RegKey rk;
if(SUCCEEDED(rk.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rk.Attach ( HC_REGISTRY_HELPSVC L"\\OEMInfo" )) &&
SUCCEEDED(rk.Delete ( /*fDeep*/true )) &&
SUCCEEDED(rk.Create ( )) )
{
WCHAR rgLine[512];
MPC::wstring strOEMInfo( L"%WINDIR%\\system32\\oeminfo.ini" ); MPC::SubstituteEnvVariables( strOEMInfo );
MPC::wstring strOEMText;
CComVariant vValue;
int i;
if(::GetPrivateProfileStringW( L"General", L"Manufacturer", L"", rgLine, MAXSTRLEN(rgLine), strOEMInfo.c_str() ) > 0)
{
vValue = rgLine; rk.put_Value( vValue, L"Manufacturer" );
}
if(::GetPrivateProfileStringW( L"General", L"Model", L"", rgLine, MAXSTRLEN(rgLine), strOEMInfo.c_str() ) > 0)
{
vValue = rgLine; rk.put_Value( vValue, L"Model" );
}
for(i=1;;i++)
{
WCHAR rgKey[64];
if (SUCCEEDED(StringCchPrintfW(rgKey, ARRAYSIZE(rgKey), L"Line%d", i)))
{
::GetPrivateProfileStringW( L"Support Information", rgKey, L"<eof>", rgLine, MAXSTRLEN(rgLine), strOEMInfo.c_str() );
if(!wcscmp( rgLine, L"<eof>" )) break;
if(strOEMText.size()) strOEMText += L"#BR#";
strOEMText += rgLine;
}
}
if(strOEMText.size())
{
vValue = strOEMText.c_str(); rk.put_Value( vValue, L"Text" );
}
dwStatus &= ~SETUP_OEMINFO;
}
}
////////////////////////////////////////////////////////////////////////////////
local_RemoveRegistryBackup();
//
// Extract all the data files.
//
{
MPC::wstring strCabinet;
//
// Find the best fit.
//
do
{
OSVERSIONINFOEXW ver;
MPC::WStringList lst;
MPC::WStringIter it;
::ZeroMemory( &ver, sizeof(ver) ); ver.dwOSVersionInfoSize = sizeof(ver);
::GetVersionExW( (LPOSVERSIONINFOW)&ver );
if(FAILED(SVC::LocateDataArchive( HC_ROOT_HELPSVC_BINARIES, lst ))) break;
if(lst.size() == 0) break;
for(it = lst.begin(); it != lst.end(); it++)
{
Installer::Package pkg;
if(SUCCEEDED(pkg.Init( it->c_str() )) &&
SUCCEEDED(pkg.Load( )) )
{
LPCWSTR szSKU = pkg.GetData().m_ths.GetSKU();
if(ver.wProductType == VER_NT_WORKSTATION)
{
if(ver.wSuiteMask & VER_SUITE_PERSONAL)
{
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_32_PERSONAL )) break;
}
else
{
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_32_PROFESSIONAL )) break;
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_64_PROFESSIONAL )) break;
}
}
else
{
if(ver.wSuiteMask & VER_SUITE_DATACENTER)
{
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_32_DATACENTER )) break;
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_64_DATACENTER )) break;
}
else if(ver.wSuiteMask & VER_SUITE_ENTERPRISE)
{
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_32_ADVANCED_SERVER )) break;
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_64_ADVANCED_SERVER )) break;
}
else
{
if(!MPC::StrICmp( szSKU, Taxonomy::s_szSKU_32_SERVER )) break;
}
}
}
}
strCabinet = *(it == lst.end() ? lst.begin() : it);
}
while(0);
if(strCabinet.size())
{
Installer::Package pkg;
if(SUCCEEDED(pkg.Init( strCabinet.c_str() )) &&
SUCCEEDED(pkg.Load( )) )
{
CComPtr<CPCHSetOfHelpTopics> sht;
if(SUCCEEDED(MPC::CreateInstance( &sht )))
{
if(SUCCEEDED(sht->DirectInstall( pkg, /*fSetup*/true, /*fSystem*/true, /*fMUI*/false )))
{
dwStatus &= ~SETUP_SKU_INSTALL;
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
{
MPC::wstring strText;
CComVariant v;
if(dwStatus)
{
if(SUCCEEDED(MPC::ConvertBitFieldToString( dwStatus, strText, c_Setup )))
{
v = strText.c_str();
}
else
{
v = (long)dwStatus;
}
}
(void)MPC::RegKey_Value_Write( v, HC_REGISTRY_HELPSVC, L"SetupProblems" );
}
hr = S_OK;
__HCP_FUNC_EXIT(hr);
}
HRESULT Local_Uninstall()
{
__HCP_FUNC_ENTRY( "Local_Uninstall" );
HRESULT hr;
MPC::wstring strGroupName;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeString( IDS_HELPSVC_GROUPNAME, strGroupName ));
////////////////////////////////////////////////////////////////////////////////
//
// Register the message file into the registry.
//
{
MPC::RegKey rkEventLog;
if(SUCCEEDED(rkEventLog.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rkEventLog.Attach ( c_szRegistryLog )) )
{
(void)rkEventLog.Delete( /*fDeep*/true );
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Create our group: "HelpServicesGroup".
//
{
CPCHAccounts acc;
(void)acc.DeleteGroup( strGroupName.c_str() );
}
////////////////////////////////////////////////////////////////////////////////
{
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( HC_ROOT_HELPSVC , NULL, /*fRemove*/true, /*fRecreate*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( HC_ROOT L"\\UploadLB", NULL, /*fRemove*/true, /*fRecreate*/false ));
}
local_RemoveRegistryBackup();
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}