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.
 
 
 
 
 
 

490 lines
14 KiB

/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
main.cpp
Abstract:
This file contains the implementation of the WinMain function for HelpSvc.
Revision History:
Davide Massarenti (Dmassare) 03/14/2000
created
******************************************************************************/
#include "stdafx.h"
#include <SvcResource.h>
#include <initguid.h>
#include "msscript.h"
#include "HelpServiceTypeLib.h"
#include "HelpServiceTypeLib_i.c"
#include "HelpCenterTypeLib.h"
#include "HelpCenterTypeLib_i.c"
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_PCHServiceReal, CPCHService )
OBJECT_ENTRY(CLSID_PCHUpdateReal , HCUpdate::Engine )
#ifndef NOJETBLUECOM
OBJECT_ENTRY(CLSID_PCHDBSessionReal , JetBlueCOM::Session)
#endif
END_OBJECT_MAP()
////////////////////////////////////////////////////////////////////////////////
static HRESULT PurgeTempFiles()
{
__HCP_FUNC_ENTRY( "PurgeTempFiles" );
HRESULT hr;
MPC::wstring szTempPath( HC_ROOT_HELPSVC_TEMP ); MPC::SubstituteEnvVariables( szTempPath );
MPC::FileSystemObject fso( szTempPath.c_str() );
MPC::FileSystemObject::List fso_lst;
MPC::FileSystemObject::IterConst fso_it;
//
// Inspect the temp directory.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, fso.CreateDir( true ));
//
// Delete any subdirectory.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, fso.EnumerateFolders( fso_lst ));
for(fso_it=fso_lst.begin(); fso_it != fso_lst.end(); fso_it++)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, (*fso_it)->Delete( true, false ));
}
fso_lst.clear();
//
// For each file, if it's not in the database, delete it.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, fso.EnumerateFiles( fso_lst ));
for(fso_it=fso_lst.begin(); fso_it != fso_lst.end(); fso_it++)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, (*fso_it)->Delete( false, false ));
}
fso_lst.clear();
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static HRESULT InitAll()
{
__HCP_FUNC_ENTRY( "InitAll" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeInit());
__MPC_EXIT_IF_METHOD_FAILS(hr, JetBlue::SessionPool ::InitializeSystem( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::InstalledInstanceStore::InitializeSystem( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::Cache ::InitializeSystem( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, OfflineCache::Root ::InitializeSystem( /*fMaster*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHContentStore ::InitializeSystem( /*fMaster*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHUserProcess ::InitializeSystem( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurity ::InitializeSystem( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSystemMonitor ::InitializeSystem( ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg ::InitializeSystem( ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static void CleanAll()
{
//
// Make sure everything is stopped before releasing any object.
//
if(Taxonomy::InstalledInstanceStore::s_GLOBAL)
{
Taxonomy::InstalledInstanceStore::s_GLOBAL->Shutdown();
}
CSAFReg ::FinalizeSystem();
CPCHSystemMonitor ::FinalizeSystem();
CPCHSecurity ::FinalizeSystem();
CPCHUserProcess ::FinalizeSystem();
CPCHContentStore ::FinalizeSystem();
OfflineCache::Root ::FinalizeSystem();
Taxonomy::Cache ::FinalizeSystem();
Taxonomy::InstalledInstanceStore::FinalizeSystem();
JetBlue::SessionPool ::FinalizeSystem();
}
static HRESULT ProcessArguments( int argc ,
LPCWSTR* argv )
{
__HCP_FUNC_ENTRY( "ProcessArguments" );
HRESULT hr;
int i;
LPCWSTR szSvcHostGroup = NULL;
bool fCOM_reg = false;
bool fCOM_unreg = false;
bool fInstall = false;
bool fUninstall = false;
bool fCollect = false;
bool fRunAsService = true;
bool fRun = true;
bool fMUI_install = false;
bool fMUI_uninstall = false;
LPCWSTR MUI_language = NULL;
CComBSTR MUI_cabinet;
__MPC_EXIT_IF_METHOD_FAILS(hr, InitAll());
for(i=1; i<argc; i++)
{
LPCWSTR szArg = argv[i];
if(szArg[0] == '-' ||
szArg[0] == '/' )
{
szArg++;
if(_wcsicmp( szArg, L"SvcHost" ) == 0 && i < argc-1)
{
szSvcHostGroup = argv[++i];
continue;
}
if(_wcsicmp( szArg, L"UnregServer" ) == 0)
{
fCOM_unreg = true;
fRun = false;
continue;
}
if(_wcsicmp( szArg, L"RegServer" ) == 0)
{
fCOM_unreg = true; // Unregister before registering. Useful in upgrade scenario.
fCOM_reg = true;
fRun = false;
continue;
}
if(_wcsicmp( szArg, L"Embedding" ) == 0)
{
fRunAsService = false;
continue;
}
if(_wcsicmp( szArg, L"Install" ) == 0)
{
fInstall = true;
fRun = false;
continue;
}
if(_wcsicmp( szArg, L"Uninstall" ) == 0)
{
fUninstall = true;
fRun = false;
continue;
}
if(_wcsicmp( szArg, L"MUI_Install" ) == 0 && i < argc-2)
{
MUI_language = argv[++i];
MUI_cabinet = argv[++i];
fMUI_install = true;
fRun = false;
continue;
}
if(_wcsicmp( szArg, L"MUI_Uninstall" ) == 0 && i < argc-1)
{
MUI_language = argv[++i];
fMUI_uninstall = true;
fRun = false;
continue;
}
if(_wcsicmp( szArg, L"Collect" ) == 0)
{
fCollect = true;
fRun = false;
continue;
}
}
__MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
}
//////////////////////////////////////////////////////////////////////
if(fCollect ||
fMUI_install ||
fMUI_uninstall )
{
try
{
CComPtr<IPCHService> svc;
long lLCID = 0;
if(MUI_language)
{
swscanf( MUI_language, L"%lx", &lLCID );
}
if(FAILED(hr = ::CoCreateInstance( CLSID_PCHService, NULL, CLSCTX_ALL, IID_IPCHService, (void**)&svc )))
{
static WCHAR s_szRunOnceKey[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
MPC::RegKey rk;
MPC::wstring szName = L"DelayedHelpSvc_";
WCHAR rgBuf[8];
if(fCollect)
{
szName += L"Collect";
}
if(fMUI_install)
{
StringCchPrintfW( rgBuf, ARRAYSIZE(rgBuf), L"%04x", (int)lLCID );
szName += L"MUI_Install_";
szName += rgBuf;
}
if(fMUI_uninstall)
{
StringCchPrintfW( rgBuf, ARRAYSIZE(rgBuf), L"%04x", (int)lLCID );
szName += L"MUI_Uninstall_";
szName += rgBuf;
}
if(SUCCEEDED(rk.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rk.Attach ( s_szRunOnceKey )) &&
SUCCEEDED(rk.Create ( )) )
{
MPC::wstring szCmd = ::GetCommandLineW();
rk.Write( szCmd, szName.c_str() );
}
__MPC_SET_ERROR_AND_EXIT(hr, S_OK);
}
if(fCollect)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, svc->TriggerScheduledDataCollection( VARIANT_TRUE ));
}
if(fMUI_install)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, svc->MUI_Install( lLCID, MUI_cabinet ));
}
if(fMUI_uninstall)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, svc->MUI_Uninstall( lLCID ));
}
}
catch(...)
{
__MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
}
__MPC_SET_ERROR_AND_EXIT(hr, S_OK);
}
//////////////////////////////////////////////////////////////////////
if(fCOM_unreg)
{
_Module.UnregisterServer( szSvcHostGroup );
}
if(fCOM_reg)
{
_Module.RegisterServer( TRUE, (szSvcHostGroup != NULL), szSvcHostGroup );
}
if(fInstall)
{
try
{
(void)Local_Install();
}
catch(...)
{
__MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
}
}
if(fUninstall)
{
try
{
(void)Local_Uninstall();
}
catch(...)
{
__MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
}
}
//////////////////////////////////////////////////////////////////////
if(fRun)
{
#ifdef DEBUG
_Module.ReadDebugSettings();
#endif
DEBUG_AppendPerf( DEBUG_PERF_HELPSVC, "Start" );
try
{
__MPC_EXIT_IF_METHOD_FAILS(hr, PurgeTempFiles());
//
// To run properly, we need this privilege.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::SetPrivilege( L"SeSecurityPrivilege" ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSystemMonitor::s_GLOBAL->Startup());
DEBUG_AppendPerf( DEBUG_PERF_HELPSVC, "Started" );
_Module.Start( fRunAsService ? TRUE : FALSE );
}
catch(...)
{
__MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
}
DEBUG_AppendPerf( DEBUG_PERF_HELPSVC, "Shutdown" );
DEBUG_DumpPerf ( L"%WINDIR%\\TEMP\\HELPSVC_perf_counters.txt" );
}
//////////////////////////////////////////////////////////////////////
hr = S_OK;
__HCP_FUNC_CLEANUP;
CleanAll();
__HCP_FUNC_EXIT(hr);
}
extern "C" int WINAPI wWinMain( HINSTANCE hInstance ,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine ,
int nShowCmd )
{
HRESULT hr;
int argc;
LPCWSTR* argv;
if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application.
{
if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
-1 , // We don't care which authentication service we use.
NULL ,
NULL ,
RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers.
RPC_C_IMP_LEVEL_IDENTIFY ,
NULL ,
EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
NULL )))
{
#ifdef PCH_DEBUG_SETUP
{
static WCHAR s_szDebugAsyncTrace[] = L"SOFTWARE\\Microsoft\\MosTrace\\CurrentVersion\\DebugAsyncTrace";
MPC::RegKey rkTrace;
if(SUCCEEDED(rkTrace.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
SUCCEEDED(rkTrace.Attach ( s_szDebugAsyncTrace )) &&
SUCCEEDED(rkTrace.Create ( )) )
{
CComVariant vValue;
vValue = (long)0x00000000 ; (void)rkTrace.put_Value( vValue, L"AsyncThreadPriority" );
vValue = (long)0x00000001 ; (void)rkTrace.put_Value( vValue, L"OutputTraceType" );
vValue = (long)500*1024*1024; (void)rkTrace.put_Value( vValue, L"MaxTraceFileSize" );
vValue = L"c:\\trace.atf" ; (void)rkTrace.put_Value( vValue, L"TraceFile" );
vValue = (long)0x00000001 ; (void)rkTrace.put_Value( vValue, L"AsyncTraceFlag" );
vValue = (long)0x0000003F ; (void)rkTrace.put_Value( vValue, L"EnabledTraces" );
}
}
#endif
__MPC_TRACE_INIT();
g_NTEvents.Init( L"HELPSVC" );
//
// Parse the command line.
//
if(SUCCEEDED(hr = MPC::CommandLine_Parse( argc, argv )))
{
//
// Initialize ATL modules.
//
_Module.Init( ObjectMap, hInstance, HC_HELPSVC_NAME, IDS_HELPSVC_DISPLAYNAME, IDS_HELPSVC_DESCRIPTION );
//
// Initialize MPC module.
//
if(SUCCEEDED(hr = MPC::_MPC_Module.Init()))
{
//
// Process arguments.
//
hr = ProcessArguments( argc, argv );
MPC::_MPC_Module.Term();
}
_Module.Term();
MPC::CommandLine_Free( argc, argv );
}
__MPC_TRACE_TERM();
}
::CoUninitialize();
}
return FAILED(hr) ? 10 : 0;
}