Source code of Windows XP (NT5)
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.

364 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: cidaemon.cxx
  7. //
  8. // Contents: CI Daemon
  9. //
  10. // History: 07-Jun-94 DwightKr Created
  11. // 18-Dec-97 KLam Removed uneeded inclusion of shtole.hxx
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <dmnproxy.hxx>
  16. #include "cidaemon.hxx"
  17. #include <ciregkey.hxx>
  18. DECLARE_INFOLEVEL(ci)
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Member: CCiDaemon::CCiDaemon
  22. //
  23. // Synopsis: Contructor of the CCiDaemon class. Creates all the necessary
  24. // objects to start filtering in the daemon process for a
  25. // catalog.
  26. //
  27. // Arguments: [nameGen] - Object used to generated shared memory and
  28. // event object names.
  29. // [dwMemSize] - Shared memory size.
  30. // [dwParentId] - ProcessId of the parent process.
  31. //
  32. // History: 1-06-97 srikants Created
  33. //
  34. //----------------------------------------------------------------------------
  35. CCiDaemon::CCiDaemon( CSharedNameGen & nameGen,
  36. DWORD dwMemSize,
  37. DWORD dwParentId )
  38. : _proxy( nameGen, dwMemSize, dwParentId )
  39. {
  40. //
  41. // Retrieve startup data for the client and then create an instance
  42. // of the client control.
  43. //
  44. ULONG cbData;
  45. GUID clsidClientMgr;
  46. BYTE const * pbData = _proxy.GetStartupData( clsidClientMgr, cbData );
  47. if ( 0 == pbData )
  48. {
  49. ciDebugOut(( DEB_ERROR, "Failed to get startup data\n" ));
  50. THROW( CException( STATUS_UNSUCCESSFUL ) );
  51. }
  52. //
  53. // Create the admin params and a simple wrapper class.
  54. //
  55. CCiAdminParams *pAdminParams = new CCiAdminParams;
  56. _xAdminParams.Set( pAdminParams );
  57. _xFwParams.Set( new CCiFrameworkParams( _xAdminParams.GetPointer() ) );
  58. //
  59. // Create the filter client object based on the Client Manager classid
  60. //
  61. // Win4Assert( FALSE );
  62. ICiCFilterClient *pTmpFilterClient;
  63. SCODE sc = CoCreateInstance( clsidClientMgr,
  64. NULL,
  65. CLSCTX_ALL,
  66. IID_ICiCFilterClient,
  67. (PVOID*)&pTmpFilterClient );
  68. if (!SUCCEEDED( sc )) {
  69. ciDebugOut(( DEB_ERROR, "Unable to bind to filter client - %x\n", sc ));
  70. THROW( CException( sc ));
  71. }
  72. XInterface<ICiCFilterClient> xFilterClient( pTmpFilterClient );
  73. //
  74. // Initialize the filter client
  75. //
  76. sc = xFilterClient->Init( pbData, cbData, _xAdminParams.GetPointer( ));
  77. if (!SUCCEEDED( sc )) {
  78. ciDebugOut(( DEB_ERROR, "FilterClient->Init failed - %x\n", sc ));
  79. THROW( CException( sc ));
  80. }
  81. // Set the process class and thread priority after admin params
  82. // are initialized by Init() above.
  83. _proxy.SetPriority( _xFwParams->GetThreadClassFilter(),
  84. _xFwParams->GetThreadPriorityFilter() );
  85. //
  86. // Set the pagefile limit. This protects against excessive VM usage.
  87. //
  88. QUOTA_LIMITS QuotaLimit;
  89. NTSTATUS Status = NtQueryInformationProcess( NtCurrentProcess(),
  90. ProcessQuotaLimits,
  91. &QuotaLimit,
  92. sizeof(QuotaLimit),
  93. 0 );
  94. if ( NT_SUCCESS(Status) )
  95. {
  96. Win4Assert( _xFwParams->GetMaxDaemonVmUse() * 1024 > _xFwParams->GetMaxDaemonVmUse() ); // Overflow check.
  97. //
  98. // The slop is because we don't want to totally trash the system with a memory allocation, but
  99. // once a leak has occurred all sorts of legitimate allocations will also fail. So in the daemon
  100. // we allow you to allocate memory slightly beyond the max, but in the watchdog checks we bail
  101. // when the limit is hit.
  102. //
  103. QuotaLimit.PagefileLimit = (_xFwParams->GetMaxDaemonVmUse() + _xFwParams->GetMaxDaemonVmUse() / 10) * 1024;
  104. Status = NtSetInformationProcess( NtCurrentProcess(),
  105. ProcessQuotaLimits,
  106. &QuotaLimit,
  107. sizeof(QuotaLimit) );
  108. if ( !NT_SUCCESS(Status) )
  109. {
  110. ciDebugOut(( DEB_ERROR, "Error 0x%x setting pagefile quota.\n", Status ));
  111. THROW( CException( Status ) );
  112. }
  113. }
  114. //
  115. // get ICiCLangRes interface pointer; used to set a CLangList instance
  116. //
  117. ICiCLangRes * pICiCLangRes = 0;
  118. sc = xFilterClient->QueryInterface(IID_ICiCLangRes, (void **) &pICiCLangRes);
  119. if ( FAILED(sc) )
  120. {
  121. THROW( CException(sc) );
  122. }
  123. XInterface<ICiCLangRes> xICiCLangRes(pICiCLangRes);
  124. _xLangList.Set( new CLangList(pICiCLangRes) );
  125. pAdminParams->SetLangList( _xLangList.GetPointer() );
  126. //
  127. // Now create the filter daemon class.
  128. //
  129. ULONG cbEntryBuf;
  130. BYTE * pbEntryBuf = _proxy.GetEntryBuffer( cbEntryBuf );
  131. CFilterDaemon * pFilterDaemon =
  132. new CFilterDaemon( _proxy,
  133. _xFwParams.GetReference(),
  134. _xLangList.GetReference(),
  135. pbEntryBuf,
  136. cbEntryBuf,
  137. xFilterClient.GetPointer( ) );
  138. _xFilterDaemon.Set( pFilterDaemon );
  139. }
  140. CCiDaemon::~CCiDaemon()
  141. {
  142. // ShutdownDaemonClient();
  143. }
  144. //+---------------------------------------------------------------------------
  145. //
  146. // Member: CCiDaemon::FilterDocuments
  147. //
  148. // Synopsis: Filters documents until death of the thread or process
  149. //
  150. // History: 1-06-97 srikants Created
  151. //
  152. //----------------------------------------------------------------------------
  153. void CCiDaemon::FilterDocuments()
  154. {
  155. SCODE scode;
  156. do
  157. {
  158. scode = _xFilterDaemon->DoUpdates();
  159. }
  160. while (scode == FDAEMON_W_WORDLISTFULL );
  161. }
  162. //+-------------------------------------------------------------------------
  163. //
  164. // Function: Usage, public
  165. //
  166. // Purpose: Displays usage message
  167. //
  168. // History: 06-Jun-94 DwightKr Created
  169. //
  170. //--------------------------------------------------------------------------
  171. void Usage()
  172. {
  173. printf("This program is part of the Ci Filter Service and can not be run standalone.\n");
  174. ciDebugOut( (DEB_ITRACE, "Ci Filter Daemon: Bad command line parameters\n" ));
  175. }
  176. //+---------------------------------------------------------------------------
  177. //
  178. // Function: RunTheDaemon
  179. //
  180. // Synopsis: The main function for the downlevel daemon process.
  181. //
  182. // Arguments: [argc] -
  183. // [argv] -
  184. //
  185. // History: 2-04-96 srikants Created
  186. //
  187. // Notes: This method is currently invoked if argc == 8. We can
  188. // change that to explicitly pass something in the first
  189. // parameter.
  190. //
  191. //----------------------------------------------------------------------------
  192. NTSTATUS RunTheDaemon( int argc, WCHAR * argv[] )
  193. {
  194. #if DBG==1
  195. ciInfoLevel = DEB_ERROR | DEB_WARN | DEB_IWARN | DEB_IERROR;
  196. #endif
  197. // Win4Assert( !"Break In" );
  198. if ( argc != 5 ||
  199. 0 != _wcsicmp( DL_DAEMON_ARG1_W, argv[1] ) ||
  200. wcslen( argv[2] ) >= MAX_PATH )
  201. {
  202. printf( "%ws %ws <catalog-dir> <SharedMemSize> <ParentId>\n",
  203. argv[0], DL_DAEMON_ARG1_W );
  204. return STATUS_INVALID_PARAMETER;
  205. }
  206. WCHAR *pwcCatalog = argv[2];
  207. DWORD dwMemSize = _wtol( argv[3] );
  208. DWORD iParentId = _wtol( argv[4] );
  209. NTSTATUS status = STATUS_SUCCESS;
  210. TRY
  211. {
  212. XCom xcom;
  213. XPtr<CSharedNameGen> xNameGen( new CSharedNameGen( pwcCatalog ) );
  214. CCiDaemon ciDaemon( xNameGen.GetReference(),
  215. dwMemSize,
  216. iParentId );
  217. //
  218. // Namegen is a fairly big class. Delete the memory.
  219. //
  220. xNameGen.Free();
  221. ciDaemon.FilterDocuments();
  222. }
  223. CATCH( CException, e)
  224. {
  225. status = e.GetErrorCode();
  226. ciDebugOut(( DEB_ERROR, "DL Filter Daemon:Exiting process, error = 0x%X\n",
  227. e.GetErrorCode() ));
  228. }
  229. END_CATCH
  230. ciDebugOut( (DEB_ITRACE, "DL Filter Daemon: Leaving main()\n" ));
  231. return status;
  232. } //RunTheDaemon
  233. //+-------------------------------------------------------------------------
  234. //
  235. // Function: main, public
  236. //
  237. // Purpose: Application entry point, sets up the service entry point
  238. // and registers the entry point with the service control
  239. // dispatcher.
  240. //
  241. // Arguments: [argc] - number of arguments passed
  242. // [argv] - arguments
  243. //
  244. // History: 06-Jun-94 DwightKr Created
  245. //
  246. //--------------------------------------------------------------------------
  247. extern "C" int __cdecl wmain( int argc, WCHAR *argv[] )
  248. {
  249. NTSTATUS status = STATUS_SUCCESS;
  250. CNoErrorMode noError;
  251. CTranslateSystemExceptions translate;
  252. TRY
  253. {
  254. #if DBG==1 || CIDBG==1
  255. ciInfoLevel = DEB_ERROR | DEB_WARN | DEB_IWARN | DEB_IERROR;
  256. #endif // DBG==1 || CIDBG==1
  257. #if CIDBG == 1
  258. BOOL fRun = TRUE; // FALSE --> Stop
  259. TRY
  260. {
  261. CRegAccess reg( RTL_REGISTRY_CONTROL, wcsRegAdmin );
  262. ULONG ulVal = reg.Read( L"StopCiDaemonOnStartup", (ULONG)0 );
  263. if ( 1 == ulVal )
  264. fRun = FALSE;
  265. }
  266. CATCH( CException, e )
  267. {
  268. }
  269. END_CATCH;
  270. unsigned long OldWin4AssertLevel = SetWin4AssertLevel(ASSRT_MESSAGE | ASSRT_POPUP);
  271. Win4Assert( fRun );
  272. SetWin4AssertLevel( OldWin4AssertLevel );
  273. #endif // CIDBG
  274. if ( argc > 2 && 0 == _wcsicmp( argv[1], DL_DAEMON_ARG1_W ) )
  275. {
  276. status = RunTheDaemon( argc, argv );
  277. }
  278. else
  279. {
  280. Usage();
  281. return 0;
  282. }
  283. }
  284. CATCH( CException, e)
  285. {
  286. ciDebugOut(( DEB_ERROR,
  287. "Unhandled error in CiDaemon: 0x%x\n",
  288. e.GetErrorCode() ));
  289. }
  290. END_CATCH
  291. // Shutdown Kyle OLE now or it'll AV later.
  292. CIShutdown();
  293. return status;
  294. } //wmain