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