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

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. main.cpp
  5. Abstract:
  6. This file contains the implementation of the WinMain function for HelpSvc.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 03/14/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include <SvcResource.h>
  13. #include <initguid.h>
  14. #include "msscript.h"
  15. #include "HelpServiceTypeLib.h"
  16. #include "HelpServiceTypeLib_i.c"
  17. #include "HelpCenterTypeLib.h"
  18. #include "HelpCenterTypeLib_i.c"
  19. BEGIN_OBJECT_MAP(ObjectMap)
  20. OBJECT_ENTRY(CLSID_PCHServiceReal, CPCHService )
  21. OBJECT_ENTRY(CLSID_PCHUpdateReal , HCUpdate::Engine )
  22. #ifndef NOJETBLUECOM
  23. OBJECT_ENTRY(CLSID_PCHDBSessionReal , JetBlueCOM::Session)
  24. #endif
  25. END_OBJECT_MAP()
  26. ////////////////////////////////////////////////////////////////////////////////
  27. static HRESULT PurgeTempFiles()
  28. {
  29. __HCP_FUNC_ENTRY( "PurgeTempFiles" );
  30. HRESULT hr;
  31. MPC::wstring szTempPath( HC_ROOT_HELPSVC_TEMP ); MPC::SubstituteEnvVariables( szTempPath );
  32. MPC::FileSystemObject fso( szTempPath.c_str() );
  33. MPC::FileSystemObject::List fso_lst;
  34. MPC::FileSystemObject::IterConst fso_it;
  35. //
  36. // Inspect the temp directory.
  37. //
  38. __MPC_EXIT_IF_METHOD_FAILS(hr, fso.CreateDir( true ));
  39. //
  40. // Delete any subdirectory.
  41. //
  42. __MPC_EXIT_IF_METHOD_FAILS(hr, fso.EnumerateFolders( fso_lst ));
  43. for(fso_it=fso_lst.begin(); fso_it != fso_lst.end(); fso_it++)
  44. {
  45. __MPC_EXIT_IF_METHOD_FAILS(hr, (*fso_it)->Delete( true, false ));
  46. }
  47. fso_lst.clear();
  48. //
  49. // For each file, if it's not in the database, delete it.
  50. //
  51. __MPC_EXIT_IF_METHOD_FAILS(hr, fso.EnumerateFiles( fso_lst ));
  52. for(fso_it=fso_lst.begin(); fso_it != fso_lst.end(); fso_it++)
  53. {
  54. __MPC_EXIT_IF_METHOD_FAILS(hr, (*fso_it)->Delete( false, false ));
  55. }
  56. fso_lst.clear();
  57. hr = S_OK;
  58. __HCP_FUNC_CLEANUP;
  59. __HCP_FUNC_EXIT(hr);
  60. }
  61. static HRESULT InitAll()
  62. {
  63. __HCP_FUNC_ENTRY( "InitAll" );
  64. HRESULT hr;
  65. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeInit());
  66. __MPC_EXIT_IF_METHOD_FAILS(hr, JetBlue::SessionPool ::InitializeSystem( ));
  67. __MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::InstalledInstanceStore::InitializeSystem( ));
  68. __MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::Cache ::InitializeSystem( ));
  69. __MPC_EXIT_IF_METHOD_FAILS(hr, OfflineCache::Root ::InitializeSystem( /*fMaster*/true ));
  70. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHContentStore ::InitializeSystem( /*fMaster*/true ));
  71. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHUserProcess ::InitializeSystem( ));
  72. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurity ::InitializeSystem( ));
  73. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSystemMonitor ::InitializeSystem( ));
  74. __MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg ::InitializeSystem( ));
  75. hr = S_OK;
  76. __HCP_FUNC_CLEANUP;
  77. __HCP_FUNC_EXIT(hr);
  78. }
  79. static void CleanAll()
  80. {
  81. //
  82. // Make sure everything is stopped before releasing any object.
  83. //
  84. if(Taxonomy::InstalledInstanceStore::s_GLOBAL)
  85. {
  86. Taxonomy::InstalledInstanceStore::s_GLOBAL->Shutdown();
  87. }
  88. CSAFReg ::FinalizeSystem();
  89. CPCHSystemMonitor ::FinalizeSystem();
  90. CPCHSecurity ::FinalizeSystem();
  91. CPCHUserProcess ::FinalizeSystem();
  92. CPCHContentStore ::FinalizeSystem();
  93. OfflineCache::Root ::FinalizeSystem();
  94. Taxonomy::Cache ::FinalizeSystem();
  95. Taxonomy::InstalledInstanceStore::FinalizeSystem();
  96. JetBlue::SessionPool ::FinalizeSystem();
  97. }
  98. static HRESULT ProcessArguments( int argc ,
  99. LPCWSTR* argv )
  100. {
  101. __HCP_FUNC_ENTRY( "ProcessArguments" );
  102. HRESULT hr;
  103. int i;
  104. LPCWSTR szSvcHostGroup = NULL;
  105. bool fCOM_reg = false;
  106. bool fCOM_unreg = false;
  107. bool fInstall = false;
  108. bool fUninstall = false;
  109. bool fCollect = false;
  110. bool fRunAsService = true;
  111. bool fRun = true;
  112. bool fMUI_install = false;
  113. bool fMUI_uninstall = false;
  114. LPCWSTR MUI_language = NULL;
  115. CComBSTR MUI_cabinet;
  116. __MPC_EXIT_IF_METHOD_FAILS(hr, InitAll());
  117. for(i=1; i<argc; i++)
  118. {
  119. LPCWSTR szArg = argv[i];
  120. if(szArg[0] == '-' ||
  121. szArg[0] == '/' )
  122. {
  123. szArg++;
  124. if(_wcsicmp( szArg, L"SvcHost" ) == 0 && i < argc-1)
  125. {
  126. szSvcHostGroup = argv[++i];
  127. continue;
  128. }
  129. if(_wcsicmp( szArg, L"UnregServer" ) == 0)
  130. {
  131. fCOM_unreg = true;
  132. fRun = false;
  133. continue;
  134. }
  135. if(_wcsicmp( szArg, L"RegServer" ) == 0)
  136. {
  137. fCOM_unreg = true; // Unregister before registering. Useful in upgrade scenario.
  138. fCOM_reg = true;
  139. fRun = false;
  140. continue;
  141. }
  142. if(_wcsicmp( szArg, L"Embedding" ) == 0)
  143. {
  144. fRunAsService = false;
  145. continue;
  146. }
  147. if(_wcsicmp( szArg, L"Install" ) == 0)
  148. {
  149. fInstall = true;
  150. fRun = false;
  151. continue;
  152. }
  153. if(_wcsicmp( szArg, L"Uninstall" ) == 0)
  154. {
  155. fUninstall = true;
  156. fRun = false;
  157. continue;
  158. }
  159. if(_wcsicmp( szArg, L"MUI_Install" ) == 0 && i < argc-2)
  160. {
  161. MUI_language = argv[++i];
  162. MUI_cabinet = argv[++i];
  163. fMUI_install = true;
  164. fRun = false;
  165. continue;
  166. }
  167. if(_wcsicmp( szArg, L"MUI_Uninstall" ) == 0 && i < argc-1)
  168. {
  169. MUI_language = argv[++i];
  170. fMUI_uninstall = true;
  171. fRun = false;
  172. continue;
  173. }
  174. if(_wcsicmp( szArg, L"Collect" ) == 0)
  175. {
  176. fCollect = true;
  177. fRun = false;
  178. continue;
  179. }
  180. }
  181. __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  182. }
  183. //////////////////////////////////////////////////////////////////////
  184. if(fCollect ||
  185. fMUI_install ||
  186. fMUI_uninstall )
  187. {
  188. try
  189. {
  190. CComPtr<IPCHService> svc;
  191. long lLCID = 0;
  192. if(MUI_language)
  193. {
  194. swscanf( MUI_language, L"%lx", &lLCID );
  195. }
  196. if(FAILED(hr = ::CoCreateInstance( CLSID_PCHService, NULL, CLSCTX_ALL, IID_IPCHService, (void**)&svc )))
  197. {
  198. static WCHAR s_szRunOnceKey[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
  199. MPC::RegKey rk;
  200. MPC::wstring szName = L"DelayedHelpSvc_";
  201. WCHAR rgBuf[8];
  202. if(fCollect)
  203. {
  204. szName += L"Collect";
  205. }
  206. if(fMUI_install)
  207. {
  208. StringCchPrintfW( rgBuf, ARRAYSIZE(rgBuf), L"%04x", (int)lLCID );
  209. szName += L"MUI_Install_";
  210. szName += rgBuf;
  211. }
  212. if(fMUI_uninstall)
  213. {
  214. StringCchPrintfW( rgBuf, ARRAYSIZE(rgBuf), L"%04x", (int)lLCID );
  215. szName += L"MUI_Uninstall_";
  216. szName += rgBuf;
  217. }
  218. if(SUCCEEDED(rk.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
  219. SUCCEEDED(rk.Attach ( s_szRunOnceKey )) &&
  220. SUCCEEDED(rk.Create ( )) )
  221. {
  222. MPC::wstring szCmd = ::GetCommandLineW();
  223. rk.Write( szCmd, szName.c_str() );
  224. }
  225. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  226. }
  227. if(fCollect)
  228. {
  229. __MPC_EXIT_IF_METHOD_FAILS(hr, svc->TriggerScheduledDataCollection( VARIANT_TRUE ));
  230. }
  231. if(fMUI_install)
  232. {
  233. __MPC_EXIT_IF_METHOD_FAILS(hr, svc->MUI_Install( lLCID, MUI_cabinet ));
  234. }
  235. if(fMUI_uninstall)
  236. {
  237. __MPC_EXIT_IF_METHOD_FAILS(hr, svc->MUI_Uninstall( lLCID ));
  238. }
  239. }
  240. catch(...)
  241. {
  242. __MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
  243. }
  244. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  245. }
  246. //////////////////////////////////////////////////////////////////////
  247. if(fCOM_unreg)
  248. {
  249. _Module.UnregisterServer( szSvcHostGroup );
  250. }
  251. if(fCOM_reg)
  252. {
  253. _Module.RegisterServer( TRUE, (szSvcHostGroup != NULL), szSvcHostGroup );
  254. }
  255. if(fInstall)
  256. {
  257. try
  258. {
  259. (void)Local_Install();
  260. }
  261. catch(...)
  262. {
  263. __MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
  264. }
  265. }
  266. if(fUninstall)
  267. {
  268. try
  269. {
  270. (void)Local_Uninstall();
  271. }
  272. catch(...)
  273. {
  274. __MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
  275. }
  276. }
  277. //////////////////////////////////////////////////////////////////////
  278. if(fRun)
  279. {
  280. #ifdef DEBUG
  281. _Module.ReadDebugSettings();
  282. #endif
  283. DEBUG_AppendPerf( DEBUG_PERF_HELPSVC, "Start" );
  284. try
  285. {
  286. __MPC_EXIT_IF_METHOD_FAILS(hr, PurgeTempFiles());
  287. //
  288. // To run properly, we need this privilege.
  289. //
  290. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::SetPrivilege( L"SeSecurityPrivilege" ));
  291. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSystemMonitor::s_GLOBAL->Startup());
  292. DEBUG_AppendPerf( DEBUG_PERF_HELPSVC, "Started" );
  293. _Module.Start( fRunAsService ? TRUE : FALSE );
  294. }
  295. catch(...)
  296. {
  297. __MPC_SET_ERROR_AND_EXIT(hr, EXCEPTION_NONCONTINUABLE_EXCEPTION);
  298. }
  299. DEBUG_AppendPerf( DEBUG_PERF_HELPSVC, "Shutdown" );
  300. DEBUG_DumpPerf ( L"%WINDIR%\\TEMP\\HELPSVC_perf_counters.txt" );
  301. }
  302. //////////////////////////////////////////////////////////////////////
  303. hr = S_OK;
  304. __HCP_FUNC_CLEANUP;
  305. CleanAll();
  306. __HCP_FUNC_EXIT(hr);
  307. }
  308. extern "C" int WINAPI wWinMain( HINSTANCE hInstance ,
  309. HINSTANCE hPrevInstance,
  310. LPWSTR lpCmdLine ,
  311. int nShowCmd )
  312. {
  313. HRESULT hr;
  314. int argc;
  315. LPCWSTR* argv;
  316. if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application.
  317. {
  318. if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
  319. -1 , // We don't care which authentication service we use.
  320. NULL ,
  321. NULL ,
  322. RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers.
  323. RPC_C_IMP_LEVEL_IDENTIFY ,
  324. NULL ,
  325. EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
  326. NULL )))
  327. {
  328. #ifdef PCH_DEBUG_SETUP
  329. {
  330. static WCHAR s_szDebugAsyncTrace[] = L"SOFTWARE\\Microsoft\\MosTrace\\CurrentVersion\\DebugAsyncTrace";
  331. MPC::RegKey rkTrace;
  332. if(SUCCEEDED(rkTrace.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS )) &&
  333. SUCCEEDED(rkTrace.Attach ( s_szDebugAsyncTrace )) &&
  334. SUCCEEDED(rkTrace.Create ( )) )
  335. {
  336. CComVariant vValue;
  337. vValue = (long)0x00000000 ; (void)rkTrace.put_Value( vValue, L"AsyncThreadPriority" );
  338. vValue = (long)0x00000001 ; (void)rkTrace.put_Value( vValue, L"OutputTraceType" );
  339. vValue = (long)500*1024*1024; (void)rkTrace.put_Value( vValue, L"MaxTraceFileSize" );
  340. vValue = L"c:\\trace.atf" ; (void)rkTrace.put_Value( vValue, L"TraceFile" );
  341. vValue = (long)0x00000001 ; (void)rkTrace.put_Value( vValue, L"AsyncTraceFlag" );
  342. vValue = (long)0x0000003F ; (void)rkTrace.put_Value( vValue, L"EnabledTraces" );
  343. }
  344. }
  345. #endif
  346. __MPC_TRACE_INIT();
  347. g_NTEvents.Init( L"HELPSVC" );
  348. //
  349. // Parse the command line.
  350. //
  351. if(SUCCEEDED(hr = MPC::CommandLine_Parse( argc, argv )))
  352. {
  353. //
  354. // Initialize ATL modules.
  355. //
  356. _Module.Init( ObjectMap, hInstance, HC_HELPSVC_NAME, IDS_HELPSVC_DISPLAYNAME, IDS_HELPSVC_DESCRIPTION );
  357. //
  358. // Initialize MPC module.
  359. //
  360. if(SUCCEEDED(hr = MPC::_MPC_Module.Init()))
  361. {
  362. //
  363. // Process arguments.
  364. //
  365. hr = ProcessArguments( argc, argv );
  366. MPC::_MPC_Module.Term();
  367. }
  368. _Module.Term();
  369. MPC::CommandLine_Free( argc, argv );
  370. }
  371. __MPC_TRACE_TERM();
  372. }
  373. ::CoUninitialize();
  374. }
  375. return FAILED(hr) ? 10 : 0;
  376. }