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
16 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. HC.cpp
  5. Abstract:
  6. This file contains the start-up code to create and initialize the Help Center.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 08/07/99
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include <DataCollection.h>
  13. #include "resource.h"
  14. #include <initguid.h>
  15. #include <HelpServiceTypeLib_i.c>
  16. #include <HelpCenterTypeLib_i.c>
  17. #include <NameSpace_Impl.h>
  18. #include "msscript.h"
  19. /////////////////////////////////////////////////////////////////////////////
  20. static const WCHAR MARSCORE_DLL [] = L"pchshell.dll";
  21. static const WCHAR HCP_PROTOCOL [] = L"HCP";
  22. static const WCHAR MSITS_PROTOCOL[] = L"MS-ITS";
  23. static const WCHAR HELPSVC_REGISTRATION[] = HC_ROOT_HELPSVC_BINARIES L"\\HelpSvc.exe /svchost netsvcs /regserver";
  24. /////////////////////////////////////////////////////////////////////////////
  25. EXTERN_C const CLSID CLSID_JavaScript = { 0xF414C260, 0x6AC0, 0x11CF, { 0xB6, 0xD1, 0x00, 0xAA, 0x00, 0xBB, 0xBB, 0x58 } };
  26. /////////////////////////////////////////////////////////////////////////////
  27. // From "mars.h"
  28. typedef int (APIENTRY *PFNMARSMAIN)(HICON hAppIcon,
  29. LPWSTR lpAppTitle,
  30. LPWSTR lpCmdLine,
  31. int nCmdShow);
  32. /////////////////////////////////////////////////////////////////////////////
  33. BEGIN_OBJECT_MAP(ObjectMap)
  34. OBJECT_ENTRY(CLSID_PCHBootstrapper , CPCHBootstrapper )
  35. OBJECT_ENTRY(CLSID_PCHHelpViewerWrapper, CPCHHelpViewerWrapper )
  36. OBJECT_ENTRY(CLSID_PCHToolBar , CPCHToolBar )
  37. OBJECT_ENTRY(CLSID_PCHProgressBar , CPCHProgressBar )
  38. OBJECT_ENTRY(CLSID_PCHJavaScriptWrapper, CPCHScriptWrapper_ClientSide< &CLSID_JavaScript >)
  39. OBJECT_ENTRY(CLSID_PCHVBScriptWrapper , CPCHScriptWrapper_ClientSide< &CLSID_VBScript >)
  40. END_OBJECT_MAP()
  41. /////////////////////////////////////////////////////////////////////////////
  42. #define DEBUG_REGKEY HC_REGISTRY_HELPCTR L"\\Debug"
  43. #define DEBUG_BREAKONSTART L"BREAKONSTART"
  44. #define DEBUG_BLOCKERRORS L"BLOCKERRORS"
  45. #define DEBUG_CONTEXTMENU L"CONTEXTMENU"
  46. #define DEBUG_BUILDTREE L"BUILDTREE"
  47. #define DEBUG_FORCESTYLE L"FORCESTYLE"
  48. #define DEBUG_FORCERTL L"FORCERTL"
  49. bool g_Debug_BLOCKERRORS = true;
  50. bool g_Debug_CONTEXTMENU = false;
  51. bool g_Debug_BUILDTREE = false;
  52. WCHAR g_Debug_FORCESTYLE[64];
  53. /////////////////////////////////////////////////////////////////////////////
  54. static bool FindMarsDLL( HMODULE& hModule ,
  55. PFNMARSTHREADPROC& pMarsThreadProc )
  56. {
  57. hModule = ::LoadLibraryW( MARSCORE_DLL );
  58. if(hModule)
  59. {
  60. pMarsThreadProc = (PFNMARSTHREADPROC)GetProcAddress( hModule, (LPCSTR)ORD_MARSTHREADPROC );
  61. if(pMarsThreadProc == NULL)
  62. {
  63. MPC::LocalizedMessageBox( IDS_HELPCTR_DLG_ERROR, IDS_HELPCTR_MARSCORE_INCORRECT_VERSION, MB_OK );
  64. return false;
  65. }
  66. }
  67. else
  68. {
  69. MPC::LocalizedMessageBox( IDS_HELPCTR_DLG_ERROR, IDS_HELPCTR_MARSCORE_NOT_FOUND, MB_OK );
  70. return false;
  71. }
  72. return true;
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. static HRESULT RegisterProtocols( /*[in/out]*/ CComPtr<IInternetSession>& pSession ,
  76. /*[in/out]*/ CComPtr<IClassFactory> & pFactoryHCP ,
  77. /*[in/out]*/ CComPtr<IClassFactory> & pFactoryMSITS )
  78. {
  79. __HCP_FUNC_ENTRY( "RegisterProtocols" );
  80. HRESULT hr;
  81. CComPtr<CHCPProtocolInfo> objHCP;
  82. CComPtr<CPCHWrapProtocolInfo> objMSITS;
  83. __MPC_EXIT_IF_METHOD_FAILS(hr, _Module.RegisterClassObjects( CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE ));
  84. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoInternetGetSession( 0, &pSession, 0 ));
  85. //
  86. // Create an instance of CHCPProtocolInfo, that acts also as a class factory for CHCPProtocol.
  87. //
  88. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &objHCP ));
  89. __MPC_EXIT_IF_METHOD_FAILS(hr, objHCP->QueryInterface( IID_IClassFactory, (void **)&pFactoryHCP ));
  90. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->RegisterNameSpace( pFactoryHCP, CLSID_HCPProtocol, HCP_PROTOCOL, 0, NULL, 0 ));
  91. //
  92. // Create an instance of CPCHWrapProtocolInfo, that acts as a wrapper around the real MS-ITS class factory.
  93. //
  94. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &objMSITS ));
  95. __MPC_EXIT_IF_METHOD_FAILS(hr, objMSITS->Init( CLSID_MSITSProtocol ));
  96. __MPC_EXIT_IF_METHOD_FAILS(hr, objMSITS->QueryInterface( IID_IClassFactory, (void **)&pFactoryMSITS ));
  97. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->RegisterNameSpace( pFactoryMSITS, CLSID_MSITSProtocol, MSITS_PROTOCOL, 0, NULL, 0 ));
  98. hr = S_OK;
  99. __HCP_FUNC_CLEANUP;
  100. __HCP_FUNC_EXIT(hr);
  101. }
  102. static HRESULT UnregisterProtocols( /*[in/out]*/ CComPtr<IInternetSession>& pSession ,
  103. /*[in/out]*/ CComPtr<IClassFactory> & pFactoryHCP ,
  104. /*[in/out]*/ CComPtr<IClassFactory> & pFactoryMSITS )
  105. {
  106. __HCP_FUNC_ENTRY( "UnregisterProtocols" );
  107. HRESULT hr;
  108. if(pSession)
  109. {
  110. if(pFactoryHCP)
  111. {
  112. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->UnregisterNameSpace( pFactoryHCP, HCP_PROTOCOL ));
  113. pFactoryHCP.Release();
  114. }
  115. if(pFactoryMSITS)
  116. {
  117. __MPC_EXIT_IF_METHOD_FAILS(hr, pSession->UnregisterNameSpace( pFactoryMSITS, MSITS_PROTOCOL ));
  118. pFactoryMSITS.Release();
  119. }
  120. pSession.Release();
  121. }
  122. __MPC_EXIT_IF_METHOD_FAILS(hr, _Module.RevokeClassObjects());
  123. hr = S_OK;
  124. __HCP_FUNC_CLEANUP;
  125. __HCP_FUNC_EXIT(hr);
  126. }
  127. ////////////////////////////////////////////////////////////////////////////////
  128. static HRESULT InitAll()
  129. {
  130. __HCP_FUNC_ENTRY( "InitAll" );
  131. HRESULT hr;
  132. // Fix environment block if necessary
  133. if (!GetEnvironmentVariableW(L"windir", NULL, 0))
  134. {
  135. // %windir% not in the env block (e.g. 16-bit apps), add it
  136. WCHAR szWindir[MAX_PATH + 1];
  137. int nChars = GetWindowsDirectory(szWindir, ARRAYSIZE(szWindir));
  138. if (nChars > 0 && nChars < ARRAYSIZE(szWindir))
  139. {
  140. SetEnvironmentVariable(L"windir", szWindir);
  141. }
  142. }
  143. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeInit());
  144. __MPC_EXIT_IF_METHOD_FAILS(hr, OfflineCache::Root ::InitializeSystem( /*fMaster*/false ));
  145. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHContentStore ::InitializeSystem( /*fMaster*/false ));
  146. __MPC_EXIT_IF_METHOD_FAILS(hr, HyperLinks::Lookup ::InitializeSystem( ));
  147. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHHelpCenterExternal ::InitializeSystem( ));
  148. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHFavorites ::InitializeSystem( ));
  149. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHOptions ::InitializeSystem( ));
  150. __MPC_EXIT_IF_METHOD_FAILS(hr, CHCPProtocolEnvironment::InitializeSystem( ));
  151. hr = S_OK;
  152. __HCP_FUNC_CLEANUP;
  153. __HCP_FUNC_EXIT(hr);
  154. }
  155. static void CleanAll()
  156. {
  157. CHCPProtocolEnvironment::FinalizeSystem();
  158. CPCHFavorites ::FinalizeSystem();
  159. CPCHOptions ::FinalizeSystem();
  160. CPCHHelpCenterExternal ::FinalizeSystem();
  161. HyperLinks::Lookup ::FinalizeSystem();
  162. CPCHContentStore ::FinalizeSystem();
  163. OfflineCache::Root ::FinalizeSystem();
  164. }
  165. ////////////////////////////////////////////////////////////////////////////////
  166. static HRESULT ProcessArguments( int argc ,
  167. LPCWSTR* argv )
  168. {
  169. __HCP_FUNC_ENTRY( "ProcessArguments" );
  170. HRESULT hr;
  171. HMODULE hModule = NULL;
  172. PFNMARSTHREADPROC pMarsThreadProc = NULL;
  173. CComPtr<IInternetSession> pSession;
  174. CComPtr<IClassFactory> pFactoryHCP;
  175. CComPtr<IClassFactory> pFactoryMSITS;
  176. bool fCOM_reg = false;
  177. bool fCOM_unreg = false;
  178. int i;
  179. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "ProcessArguments" );
  180. __MPC_EXIT_IF_METHOD_FAILS(hr, InitAll());
  181. for(i=1; i<argc; i++)
  182. {
  183. LPCWSTR szArg = argv[i];
  184. if(szArg[0] == '-' ||
  185. szArg[0] == '/' )
  186. {
  187. szArg++;
  188. if(_wcsicmp( szArg, L"RegServer" ) == 0) fCOM_reg = true;
  189. if(_wcsicmp( szArg, L"UnregServer" ) == 0) fCOM_unreg = true;
  190. }
  191. }
  192. if(fCOM_reg || fCOM_unreg)
  193. {
  194. MPC::wstring strDir( HC_ROOT_HELPSVC_BINARIES ); MPC::SubstituteEnvVariables( strDir );
  195. struct _ATL_REGMAP_ENTRY rgREG[] =
  196. {
  197. { L"BINARIES", strDir.c_str() },
  198. { NULL , NULL }
  199. };
  200. _Module.UpdateRegistryFromResource( IDR_HC, fCOM_reg ? TRUE : FALSE, rgREG );
  201. if(fCOM_reg)
  202. {
  203. _Module.RegisterTypeLib( _T("\\1") );
  204. _Module.RegisterTypeLib( _T("\\2") );
  205. }
  206. if(fCOM_unreg)
  207. {
  208. _Module.UnRegisterTypeLib( _T("\\1") );
  209. _Module.UnRegisterTypeLib( _T("\\2") );
  210. }
  211. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  212. }
  213. //////////////////////////////////////////////////////////////////////
  214. {
  215. MPC::RegKey rkBase;
  216. bool fFound;
  217. if(SUCCEEDED(rkBase.SetRoot( HKEY_LOCAL_MACHINE )) &&
  218. SUCCEEDED(rkBase.Attach ( DEBUG_REGKEY )) &&
  219. SUCCEEDED(rkBase.Exists ( fFound )) && fFound)
  220. {
  221. CComVariant vValue;
  222. #ifdef DEBUG
  223. if(SUCCEEDED(rkBase.get_Value( vValue, fFound, DEBUG_BREAKONSTART )) && fFound && vValue.vt == VT_I4)
  224. {
  225. if(vValue.lVal) DebugBreak();
  226. }
  227. g_Debug_CONTEXTMENU = true;
  228. g_Debug_BUILDTREE = true;
  229. if(SUCCEEDED(rkBase.get_Value( vValue, fFound, DEBUG_FORCESTYLE )) && fFound && vValue.vt == VT_BSTR && vValue.bstrVal)
  230. {
  231. wcsncpy( g_Debug_FORCESTYLE, vValue.bstrVal, MAXSTRLEN(g_Debug_FORCESTYLE) );
  232. }
  233. if(SUCCEEDED(rkBase.get_Value( vValue, fFound, DEBUG_FORCERTL )) && fFound && vValue.vt == VT_I4)
  234. {
  235. if(vValue.lVal) ::SetProcessDefaultLayout( LAYOUT_RTL );
  236. }
  237. #endif
  238. if(SUCCEEDED(rkBase.get_Value( vValue, fFound, DEBUG_BLOCKERRORS )) && fFound && vValue.vt == VT_I4)
  239. {
  240. g_Debug_BLOCKERRORS = (vValue.lVal != 0);
  241. }
  242. if(SUCCEEDED(rkBase.get_Value( vValue, fFound, DEBUG_CONTEXTMENU )) && fFound && vValue.vt == VT_I4)
  243. {
  244. g_Debug_CONTEXTMENU = (vValue.lVal != 0);
  245. }
  246. if(SUCCEEDED(rkBase.get_Value( vValue, fFound, DEBUG_BUILDTREE )) && fFound && vValue.vt == VT_I4)
  247. {
  248. g_Debug_BUILDTREE = (vValue.lVal != 0);
  249. }
  250. }
  251. }
  252. //////////////////////////////////////////////////////////////////////
  253. __MPC_EXIT_IF_METHOD_FAILS(hr, RegisterProtocols( pSession, pFactoryHCP, pFactoryMSITS ));
  254. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHHelpCenterExternal::s_GLOBAL->Initialize());
  255. //
  256. // Look for the service and warn the user if we cannot find it.
  257. //
  258. if(CPCHHelpCenterExternal::s_GLOBAL->IsServiceRunning() == false)
  259. {
  260. //
  261. // Bug 535303 SVR: Security: Help And Support Service Resets to Automatic after Set to Disabled
  262. // Modified 4/24 gschua
  263. //
  264. //
  265. // Try re-registering the service.
  266. //
  267. /*
  268. {
  269. MPC::wstring strCmdLine( HELPSVC_REGISTRATION ); MPC::SubstituteEnvVariables( strCmdLine );
  270. (void)MPC::ExecuteCommand( strCmdLine );
  271. }
  272. if(CPCHHelpCenterExternal::s_GLOBAL->IsServiceRunning() == false)
  273. {
  274. MPC::LocalizedMessageBox( IDS_HELPCTR_DLG_ERROR, IDS_HELPCTR_SVC_MISSING, MB_OK );
  275. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  276. }
  277. */
  278. MPC::LocalizedMessageBox( IDS_HELPCTR_DLG_ERROR, IDS_HELPCTR_SVC_MISSING, MB_OK );
  279. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  280. }
  281. for(i=1; i<argc; i++)
  282. {
  283. LPCWSTR szArg = argv[i];
  284. if(szArg[0] == '-' ||
  285. szArg[0] == '/' )
  286. {
  287. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHHelpCenterExternal::s_GLOBAL->ProcessArgument( i, &szArg[1], argc, argv ));
  288. }
  289. }
  290. if(CPCHHelpCenterExternal::s_GLOBAL->DoWeNeedUI())
  291. {
  292. MPC::wstring szTitle; MPC::LocalizeString( IDS_MAINWND_TITLE, szTitle );
  293. {
  294. INITCOMMONCONTROLSEX icc;
  295. icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
  296. icc.dwICC = ICC_USEREX_CLASSES | ICC_COOL_CLASSES | ICC_INTERNET_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_NATIVEFNTCTL_CLASS;
  297. ::InitCommonControlsEx( &icc );
  298. }
  299. //
  300. // Load the UI.
  301. //
  302. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "UI - Pre FindMarsDLL" );
  303. if(FindMarsDLL( hModule, pMarsThreadProc ))
  304. {
  305. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "UI - Post FindMarsDLL" );
  306. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "UI - Ready to go" );
  307. hr = CPCHHelpCenterExternal::s_GLOBAL->RunUI( szTitle, pMarsThreadProc );
  308. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "UI - Passivating" );
  309. }
  310. }
  311. //////////////////////////////////////////////////////////////////////
  312. hr = S_OK;
  313. __HCP_FUNC_CLEANUP;
  314. if(hModule) ::FreeLibrary( hModule );
  315. (void)UnregisterProtocols( pSession, pFactoryHCP, pFactoryMSITS );
  316. CleanAll();
  317. __HCP_FUNC_EXIT(hr);
  318. }
  319. extern "C" int WINAPI wWinMain( HINSTANCE hInstance ,
  320. HINSTANCE hPrevInstance,
  321. LPWSTR lpCmdLine ,
  322. int nShowCmd )
  323. {
  324. HRESULT hr;
  325. int argc;
  326. LPCWSTR* argv;
  327. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "wWinMain" );
  328. if(SUCCEEDED(hr = ::CoInitialize( NULL )))
  329. {
  330. if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
  331. -1 , // We don't care which authentication service we use.
  332. NULL ,
  333. NULL ,
  334. RPC_C_AUTHN_LEVEL_CONNECT, // We want to identify the callers.
  335. RPC_C_IMP_LEVEL_DELEGATE , // We want to be able to forward the caller's identity.
  336. NULL ,
  337. EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
  338. NULL )))
  339. {
  340. __MPC_TRACE_INIT();
  341. //
  342. // Parse the command line.
  343. //
  344. if(SUCCEEDED(hr = MPC::CommandLine_Parse( argc, argv )))
  345. {
  346. //
  347. // Initialize ATL modules.
  348. //
  349. _Module.Init( ObjectMap, hInstance, L"helpctr", 0, 0 );
  350. //
  351. // Initialize MPC module.
  352. //
  353. if(SUCCEEDED(hr = MPC::_MPC_Module.Init()))
  354. {
  355. //
  356. // Process arguments.
  357. //
  358. hr = ProcessArguments( argc, argv );
  359. MPC::_MPC_Module.Term();
  360. }
  361. _Module.Term();
  362. MPC::CommandLine_Free( argc, argv );
  363. }
  364. __MPC_TRACE_TERM();
  365. }
  366. ::CoUninitialize();
  367. }
  368. DEBUG_AppendPerf( DEBUG_PERF_BASIC, "Shutdown" );
  369. DEBUG_DumpPerf ( L"%WINDIR%\\TEMP\\HC_perf_counters.txt" );
  370. return FAILED(hr) ? 10 : 0;
  371. }